diff --git a/system/biu.v b/system/biu.v index 1dce1b3..4e1779a 100644 --- a/system/biu.v +++ b/system/biu.v @@ -23,7 +23,8 @@ `define BIU_HALT 4'b0000 `define BIU_NEXT_ACTION 4'b0001 `define BIU_READ 4'b0010 -`define BIU_RESET 4'b0011 +`define BIU_RESET1 4'b0011 +`define BIU_RESET2 4'b1111 `define BIU_PUT_BYTE 4'b0100 `define BIU_PUT_UNALIGNED_16BIT_DATA 4'b0101 @@ -86,13 +87,15 @@ reg [`L1_CACHE_SIZE-1:0] FIFO_end; /*exclusive*/ wire [`L1_CACHE_SIZE-1:0] FIFO_SIZE = FIFO_end-FIFO_start; reg [3:0] biu_state; +reg sane; always @(negedge reset) begin biu_state <= `BIU_HALT; write <= 1; + sane <= 0; end always @(posedge reset) begin - biu_state <= `BIU_RESET; + biu_state <= `BIU_RESET1; /* verilator lint_off BLKSEQ */ FIFO_start = `L1_CACHE_SIZE'b0; FIFO_end = `L1_CACHE_SIZE'b0; @@ -109,10 +112,6 @@ assign external_address_bus= func ? INSTRUCTION_ADDRESS : DATA_ADDRESS ; always @(posedge clock) begin if ( jump_req_latch ) begin - /* verilator lint_off BLKSEQ */ - FIFO_start = 0; - FIFO_end = 0; - /* verilator lint_on BLKSEQ */ INSTRUCTION_ADDRESS <= { 4'b0 , ADDRESS_INPUT }; INSTRUCTION_LOCATION <= ADDRESS_INPUT; func <= 1; @@ -155,45 +154,6 @@ always @(posedge clock) begin end end - `ifdef EARLY_VALID_INSTRUCTION - - if(FIFO_start==FIFO_end) begin - /*TODO: I would use FIFO_SIZE==0 here or better yet add an else at the - end but since FIFO_start and FIFO_end are updated in a blocking - manner it seems that the assign statement updating FIFO_SIZE - doesn't work. PLEASE CLEAN UP THIS MESS */ - VALID_INSTRUCTION <= 0; - end else if((Isit1==1) && (FIFO_SIZE!=0))begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - end else if((fifoIsize==2) && (FIFO_SIZE > `L1_CACHE_SIZE'd1))begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - end else if((fifoIsize==3) && (FIFO_SIZE > `L1_CACHE_SIZE'd2))begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; - end else if(FIFO_SIZE > `L1_CACHE_SIZE'd3)begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; - INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; - end - `else - if(FIFO_start==FIFO_end) begin - /*TODO: Same as on the first statment on the other side of the `ifdef */ - VALID_INSTRUCTION <= 0; - end else if(FIFO_SIZE>`L1_CACHE_SIZE'd3)begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; - INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; - end - `endif end @@ -201,21 +161,21 @@ always @(posedge clock) begin /*************** INSTRUCTION FIFO READ ***************/ `BIU_READ: begin if(INSTRUCTION_ADDRESS[0:0]==0 && FIFO_SIZE<{{(`L1_CACHE_SIZE-1){1'b1}},1'b0})begin - INPUT_FIFO[FIFO_end] <= external_data_bus[7:0]; - INPUT_FIFO[FIFO_end+`L1_CACHE_SIZE'd1] <= external_data_bus[15:8]; /* verilator lint_off BLKSEQ */ + INPUT_FIFO[FIFO_end] = external_data_bus[7:0]; + INPUT_FIFO[FIFO_end+`L1_CACHE_SIZE'd1] = external_data_bus[15:8]; FIFO_end = FIFO_end+`L1_CACHE_SIZE'd2; /* verilator lint_on BLKSEQ */ INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+20'd2; end else if(INSTRUCTION_ADDRESS[0:0]==0)begin - INPUT_FIFO[FIFO_end] <= external_data_bus[7:0]; /* verilator lint_off BLKSEQ */ + INPUT_FIFO[FIFO_end] = external_data_bus[7:0]; FIFO_end = FIFO_end+`L1_CACHE_SIZE'd1; /* verilator lint_on BLKSEQ */ INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+20'd1; end else begin - INPUT_FIFO[FIFO_end] <= external_data_bus[15:8]; /* verilator lint_off BLKSEQ */ + INPUT_FIFO[FIFO_end] = external_data_bus[15:8]; FIFO_end = FIFO_end+`L1_CACHE_SIZE'd1; /* verilator lint_on BLKSEQ */ INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+20'd1; @@ -320,7 +280,11 @@ always @(posedge clock) begin end /*************** HOUSE KEEPING ***************/ - `BIU_RESET: begin + `BIU_RESET1: begin + biu_state <= `BIU_RESET2; + VALID_DATA <= 0; + end + `BIU_RESET2: begin /* verilator lint_off BLKSEQ */ FIFO_start = `L1_CACHE_SIZE'b0; FIFO_end = `L1_CACHE_SIZE'b0; @@ -328,9 +292,9 @@ always @(posedge clock) begin biu_state <= `BIU_NEXT_ACTION; INSTRUCTION_ADDRESS <= 20'h0FFF0; INSTRUCTION_LOCATION <= 16'hFFF0; - VALID_INSTRUCTION <= 0; VALID_DATA <= 0; DATA_DIR <= 0; + sane<=1; end default: begin biu_state <= `BIU_NEXT_ACTION;/*Should be unreachable*/ @@ -362,34 +326,84 @@ always @( valid_instruction_ack ) begin FIFO_start = FIFO_start + {{`L1_CACHE_SIZE-3{1'b0}},Isize}; /* verilator lint_on BLKSEQ */ INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {13'd0,Isize}; - `ifdef DOUBLE_INSTRUCTION_LOAD - if(FIFO_SIZE>`L1_CACHE_SIZE'd3+{{`L1_CACHE_SIZE-3{1'b0}},Isize})begin - if((fifoIsize2==2) && (FIFO_SIZE > `L1_CACHE_SIZE'd1+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize}))begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - end else if((fifoIsize2==3) && (FIFO_SIZE > `L1_CACHE_SIZE'd2+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize}))begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; - end else if(FIFO_SIZE>`L1_CACHE_SIZE'd3+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize})begin - VALID_INSTRUCTION <= 1; - INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; - INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; - INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; - INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; - end else - VALID_INSTRUCTION <= 0; - end else begin - VALID_INSTRUCTION <= 0; +end + +always @( FIFO_start or FIFO_end ) begin + if(sane==1) begin + if(VALID_INSTRUCTION == 1 ) begin + `ifdef DOUBLE_INSTRUCTION_LOAD + if(FIFO_SIZE>`L1_CACHE_SIZE'd3+{{`L1_CACHE_SIZE-3{1'b0}},Isize})begin + if((fifoIsize2==2) && (FIFO_SIZE > `L1_CACHE_SIZE'd1+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize}))begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + end else if((fifoIsize2==3) && (FIFO_SIZE > `L1_CACHE_SIZE'd2+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize}))begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; + end else if(FIFO_SIZE>`L1_CACHE_SIZE'd3+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize})begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; + INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; + end else + VALID_INSTRUCTION <= 0; + end else begin + VALID_INSTRUCTION <= 0; + end + `else + VALID_INSTRUCTION <= 0; + `endif + end else begin + //$display("trig fifoIsize=%d %d/%d [%02x %02x]",fifoIsize,FIFO_start,FIFO_end,INPUT_FIFO[FIFO_start],INPUT_FIFO[FIFO_start+1]); + `ifdef EARLY_VALID_INSTRUCTION + if(FIFO_start==FIFO_end) begin + /*TODO: I would use FIFO_SIZE==0 here or better yet add an else at the + end but since FIFO_start and FIFO_end are updated in a blocking + manner it seems that the assign statement updating FIFO_SIZE + doesn't work. PLEASE CLEAN UP THIS MESS */ + VALID_INSTRUCTION <= 0; + end else if((Isit1==1) && (FIFO_SIZE!=0))begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + end else if((fifoIsize==2) && (FIFO_SIZE > `L1_CACHE_SIZE'd1))begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + end else if((fifoIsize==3) && (FIFO_SIZE > `L1_CACHE_SIZE'd2))begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; + end else if(FIFO_SIZE > `L1_CACHE_SIZE'd3)begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; + INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; + end + `else + if(FIFO_start==FIFO_end) begin + /*TODO: Same as on the first statment on the other side of the `ifdef */ + VALID_INSTRUCTION <= 0; + end else if(FIFO_SIZE>`L1_CACHE_SIZE'd3)begin + VALID_INSTRUCTION <= 1; + INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; + INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; + INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; + INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; + end + `endif + end end - `else - VALID_INSTRUCTION <= 0; - `endif end always @( posedge jump_req ) begin + /* verilator lint_off BLKSEQ */ + FIFO_start = FIFO_end ; + /* verilator lint_on BLKSEQ */ jump_req_latch <= 1; DATA_DIR <= 1; VALID_INSTRUCTION <= 0; diff --git a/system/decoder.v b/system/decoder.v index 99d21b3..8a5f09a 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -1031,36 +1031,36 @@ endmodule module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT ); always @( IN ) begin casez(IN) - 11'b0000_010?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* ADD - Add Immediate word/byte to accumulator */ - 11'b1000_00??_101 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* SUB - Subtract immediate word/byte from register/memory */ - 11'b1000_00??_000 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* ADD - Add Immediate word/byte to register/memory */ - 11'b1000_00??_111 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* CMP - compare Immediate with register / memory */ - 11'b1011_????_??? : VERDICT <= 3'd2+{2'b0,IN[6:6]}; /* MOV - Move Immediate byte to register */ - 11'b1000_10??_??? : VERDICT <= 3'd2; /* MOV - Reg/Mem to/from register */ - 11'b0100_????_??? : VERDICT <= 3'd1; /* DEC - Decrement Register | INC - Increment Register */ - 11'b1111_111?_00? : VERDICT <= 3'd2; /* INC - Register/Memory | DEC - Register/Memory */ - 11'b1111_0100_??? : VERDICT <= 3'd1; /* HLT - Halt */ - 11'b0011_110?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* CMP - Compare Immediate with accumulator */ - 11'b0111_????_??? : VERDICT <= 3'd2; /* Conditional relative jumps ( JE/JZ, JS/JNS ... ) */ - 11'b1110_1011_??? : VERDICT <= 3'd2; /* JMP - Unconditional jump direct within segment (short) */ - 11'b1110_1000_??? : VERDICT <= 3'd3; /* CALL - Direct call within segment */ - 11'b1100_0011_??? : VERDICT <= 3'd1; /* RET - Return from call within segment */ - 11'b1010_101?_??? : VERDICT <= 3'd1; /* STOS - Write byte/word to [DI] and increment accordingly */ - 11'b0101_0???_??? : VERDICT <= 3'd1; /* PUSH - SP-=2; [SP]=REG */ - 11'b1111_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ - 11'b0101_1???_??? : VERDICT <= 3'd1; /* POP - REG=[SP]; SP+=2 */ - 11'b1111_1111_100 : VERDICT <= 3'd2; /* JMP - Unconditional indirect within segment jump */ - 11'b1100_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* MOV - Move immediate to register/memory */ - 11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */ - 11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */ - 11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */ - 11'b1000_000?_100 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* AND - Bitwise AND immediate and register/mem */ - 11'b1000_000?_001 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* OR - Bitwise OR immediate and register/mem */ - 11'b1010_100?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ - 11'b0000_00??_??? : VERDICT <= 3'd2; /* ADD - Reg/memory with register to either */ - 11'b0010_10??_??? : VERDICT <= 3'd2; /* SUB - Reg/memory with register to either */ - 11'b0011_10??_??? : VERDICT <= 3'd2; /* CMP - Compare Register/memory and register */ - default:begin end + 11'b0000_010?_??? : VERDICT = 3'd2+{2'b0,IN[3:3]}; /* ADD - Add Immediate word/byte to accumulator */ + 11'b1000_00??_101 : VERDICT = 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* SUB - Subtract immediate word/byte from register/memory */ + 11'b1000_00??_000 : VERDICT = 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* ADD - Add Immediate word/byte to register/memory */ + 11'b1000_00??_111 : VERDICT = 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* CMP - compare Immediate with register / memory */ + 11'b1011_????_??? : VERDICT = 3'd2+{2'b0,IN[6:6]}; /* MOV - Move Immediate byte to register */ + 11'b1000_10??_??? : VERDICT = 3'd2; /* MOV - Reg/Mem to/from register */ + 11'b0100_????_??? : VERDICT = 3'd1; /* DEC - Decrement Register | INC - Increment Register */ + 11'b1111_111?_00? : VERDICT = 3'd2; /* INC - Register/Memory | DEC - Register/Memory */ + 11'b1111_0100_??? : VERDICT = 3'd1; /* HLT - Halt */ + 11'b0011_110?_??? : VERDICT = 3'd2+{2'b0,IN[3:3]}; /* CMP - Compare Immediate with accumulator */ + 11'b0111_????_??? : VERDICT = 3'd2; /* Conditional relative jumps ( JE/JZ, JS/JNS ... ) */ + 11'b1110_1011_??? : VERDICT = 3'd2; /* JMP - Unconditional jump direct within segment (short) */ + 11'b1110_1000_??? : VERDICT = 3'd3; /* CALL - Direct call within segment */ + 11'b1100_0011_??? : VERDICT = 3'd1; /* RET - Return from call within segment */ + 11'b1010_101?_??? : VERDICT = 3'd1; /* STOS - Write byte/word to [DI] and increment accordingly */ + 11'b0101_0???_??? : VERDICT = 3'd1; /* PUSH - SP-=2; [SP]=REG */ + 11'b1111_011?_000 : VERDICT = 3'd3+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ + 11'b0101_1???_??? : VERDICT = 3'd1; /* POP - REG=[SP]; SP+=2 */ + 11'b1111_1111_100 : VERDICT = 3'd2; /* JMP - Unconditional indirect within segment jump */ + 11'b1100_011?_000 : VERDICT = 3'd3+{2'b0,IN[3:3]}; /* MOV - Move immediate to register/memory */ + 11'b1100_1101_??? : VERDICT = 3'd2; /* INT - execute interrupt handler */ + 11'b1110_011?_??? : VERDICT = 3'd2; /* OUT - write AL or AX to a defined output port */ + 11'b1100_1111_??? : VERDICT = 3'd1; /* IRET - Return from interrupt */ + 11'b1000_000?_100 : VERDICT = 3'd3+{2'b0,IN[3:3]}; /* AND - Bitwise AND immediate and register/mem */ + 11'b1000_000?_001 : VERDICT = 3'd3+{2'b0,IN[3:3]}; /* OR - Bitwise OR immediate and register/mem */ + 11'b1010_100?_??? : VERDICT = 3'd2+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ + 11'b0000_00??_??? : VERDICT = 3'd2; /* ADD - Reg/memory with register to either */ + 11'b0010_10??_??? : VERDICT = 3'd2; /* SUB - Reg/memory with register to either */ + 11'b0011_10??_??? : VERDICT = 3'd2; /* CMP - Compare Register/memory and register */ + default: VERDICT = 3'd7; endcase end endmodule @@ -1069,14 +1069,14 @@ endmodule module Is1 ( input [7:0] IN, output reg VERDICT ); always @( IN ) begin casez(IN) - 8'b0100_???? : VERDICT <= 1; /* DEC - Decrement Register | INC - Increment Register */ - 8'b1111_0100 : VERDICT <= 1; /* HLT - Halt */ - 8'b1100_0011 : VERDICT <= 1; /* RET - Return from call within segment */ - 8'b1010_101? : VERDICT <= 1; /* STOS - Write byte/word to [DI] and increment accordingly */ - 8'b0101_0??? : VERDICT <= 1; /* PUSH - SP-=2; [SP]=REG */ - 8'b0101_1??? : VERDICT <= 1; /* POP - REG=[SP]; SP+=2 */ - 8'b1100_1111 : VERDICT <= 1; /* IRET - Return from interrupt */ - default:begin VERDICT<= 0; end + 8'b0100_???? : VERDICT = 1; /* DEC - Decrement Register | INC - Increment Register */ + 8'b1111_0100 : VERDICT = 1; /* HLT - Halt */ + 8'b1100_0011 : VERDICT = 1; /* RET - Return from call within segment */ + 8'b1010_101? : VERDICT = 1; /* STOS - Write byte/word to [DI] and increment accordingly */ + 8'b0101_0??? : VERDICT = 1; /* PUSH - SP-=2; [SP]=REG */ + 8'b0101_1??? : VERDICT = 1; /* POP - REG=[SP]; SP+=2 */ + 8'b1100_1111 : VERDICT = 1; /* IRET - Return from interrupt */ + default:begin VERDICT = 0; end endcase end endmodule