From df2975fa09c00091a801a3e3079607a629c2d5a1 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Sat, 4 Nov 2023 11:04:22 +0000 Subject: [PATCH] Fixed a lot of "conflicting driver" issues but I had to roll back an optimisation --- system/biu.v | 62 +++++++-------- system/config.v | 4 +- system/decoder.v | 175 ++++++++++++++++++------------------------- system/execute.v | 6 +- system/system.v | 2 +- system/testbench.cpp | 1 + system/testbench.v | 14 ++-- 7 files changed, 121 insertions(+), 143 deletions(-) diff --git a/system/biu.v b/system/biu.v index 250b10d..b397542 100644 --- a/system/biu.v +++ b/system/biu.v @@ -322,33 +322,33 @@ 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 + //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 @@ -375,7 +375,8 @@ always @( FIFO_start or FIFO_end ) begin 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 + end else + VALID_INSTRUCTION <= 0; `else if(FIFO_start==FIFO_end) begin /*TODO: Same as on the first statment on the other side of the `ifdef */ @@ -386,9 +387,10 @@ always @( FIFO_start or FIFO_end ) begin 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 + end else + VALID_INSTRUCTION <= 0; `endif - end + //end end end diff --git a/system/config.v b/system/config.v index b70067f..d686781 100644 --- a/system/config.v +++ b/system/config.v @@ -34,8 +34,10 @@ * for the maximum instruction size worth of bytes */ `define EARLY_VALID_INSTRUCTION +/*********** CURRENTLY DOESN'T WORK *************/ /* Enables the ability in BIU to pre-decode two instructions, one after the other in memory*/ -`define DOUBLE_INSTRUCTION_LOAD +//`define DOUBLE_INSTRUCTION_LOAD +/************************************************/ /* Size is in powers of two with minimal 3. * 3 : 8 Bytes diff --git a/system/decoder.v b/system/decoder.v index 033658e..fc88108 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -62,7 +62,9 @@ module decoder( reg SIMPLE_MICRO; /* use simple decodings (=0) or microcode data (=1) */ wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry; reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr; +/* verilator lint_off UNUSEDSIGNAL */ wire DEPENDS_ON_PREVIOUS; +/* verilator lint_on UNUSEDSIGNAL */ wire set_params; wire MEM_OR_IO, HALT,Wbit,memio_address_select; @@ -89,33 +91,8 @@ instruction_decode instruction_decode( /* */ ,reg_write_addr, reg_read_port2_addr, reg_read_port1_addr ); -reg [`DE_STATE_BITS-1:0] de_state; -always @(negedge reset) begin - de_state <= `DE_HALT; //TODO: race condition ?? - `ifdef CALCULATE_IPC - new_instruction<=0; - `endif - valid_exec_data<=0; - instant_response <= 0; - stalled_response <= 0; -end - -always @(posedge reset) begin - de_state <= `DE_STATE_ENTRY; - /* need early init */ - ucode_seq_addr <= `UCODE_NO_INSTRUCTION; - SIMPLE_MICRO <= 0; - owe_set_init <= 0; - set_initial_values<=0; - wait_exec<=0; - first_ucode <= 0; - HALT_LATCHED <= 0; - ERROR_LATCHED <= `ERROR_BITS'h0; - VALID_INSTRUCTION_ACK <= 0; -end - wire [2:0] instr_end; InstrSize InstrSize({IF2DE_INSTRUCTION[31:24],IF2DE_INSTRUCTION[21:19]},instr_end); @@ -127,91 +104,83 @@ reg owe_set_init; reg VALID_INSTRUCTION_lc; always @(VALID_INSTRUCTION)begin VALID_INSTRUCTION_lc<=VALID_INSTRUCTION; end -reg instant_response, stalled_response; -reg wait_exec; -always @(next_exec) begin - de_state<=`DE_STATE_ENTRY; - if ( VALID_INSTRUCTION_lc == 1 && DEPENDS_ON_PREVIOUS == 0 && ucode_seq_addr_entry==`UCODE_NO_INSTRUCTION) begin - instant_response <= !instant_response; +always @(posedge clock)begin + if(reset==0)begin + `ifdef CALCULATE_IPC + new_instruction<=0; + `endif + valid_exec_data<=0; + ucode_seq_addr <= `UCODE_NO_INSTRUCTION; + SIMPLE_MICRO <= 0; + owe_set_init <= 0; + set_initial_values<=0; + first_ucode <= 0; + HALT_LATCHED <= 0; + ERROR_LATCHED <= `ERROR_BITS'h0; + VALID_INSTRUCTION_ACK <= 0; end else begin - wait_exec<=0; + if(next_exec==1'b1)begin + if ( ( VALID_INSTRUCTION_lc == 1 || SIMPLE_MICRO == 1 ) /*&& DEPENDS_ON_PREVIOUS == 0 && ucode_seq_addr_entry==`UCODE_NO_INSTRUCTION*/) begin + //`define LATCH(VAR) VAR_LATCHED <= VAR; //TODO would this work? + IN_MOD_LATCHED <= IN_MOD; + OUT_MOD_LATCHED <= OUT_MOD; + RM_LATCHED <= RM; + MEM_OR_IO_LATCHED <= MEM_OR_IO; + PARAM1_LATCHED <= PARAM1; + PARAM2_LATCHED <= PARAM2; + ALU_OP_LATCHED <= ALU_OP; + in_alu_sel1_LATCHED <= in_alu_sel1; + in_alu_sel2_LATCHED <= in_alu_sel2; + reg_read_port1_addr_LATCHED <= reg_read_port1_addr; + reg_read_port2_addr_LATCHED <= reg_read_port2_addr; + reg_write_addr_LATCHED <= reg_write_addr; + Wbit_LATCHED <= Wbit; + ERROR_LATCHED <= ERROR; + HALT_LATCHED <= HALT; + next_state_LATCHED <= next_state; + memio_address_select_LATCHED <= memio_address_select; + + if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin + /* switch to microcode decoding */ + ucode_seq_addr <= ucode_seq_addr_entry; + SIMPLE_MICRO <= 1; + first_ucode <= 1; + set_initial_values <= !set_initial_values; + end else begin + if(SIMPLE_MICRO==0||first_ucode==1||owe_set_init==1)begin + first_ucode <= 0; + /* This runs at the start of the execution of an 8086 instruction */ + `ifdef DEBUG_PC_ADDRESS + $display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,IF2DE_INSTRUCTION); + `endif + `ifdef CALCULATE_IPC + new_instruction <= !new_instruction; + `endif + owe_set_init<=0; + ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end}; + VALID_INSTRUCTION_ACK <= !VALID_INSTRUCTION_ACK; + end + if(set_params)begin + set_initial_values <= !set_initial_values; + end + /* This runs at the start of each execution cycle, with microcode this is more than once per 8086 instruction */ + valid_exec_data<=!valid_exec_data; + if( SIMPLE_MICRO == 1 ) begin + ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ + if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin + /*Finished microcode*/ + SIMPLE_MICRO <= 0; + end + end + end + end + end end end reg first_ucode; -always @(instant_response or stalled_response) begin - //`define LATCH(VAR) VAR_LATCHED <= VAR; //TODO would this work? - IN_MOD_LATCHED <= IN_MOD; - OUT_MOD_LATCHED <= OUT_MOD; - RM_LATCHED <= RM; - MEM_OR_IO_LATCHED <= MEM_OR_IO; - PARAM1_LATCHED <= PARAM1; - PARAM2_LATCHED <= PARAM2; - ALU_OP_LATCHED <= ALU_OP; - in_alu_sel1_LATCHED <= in_alu_sel1; - in_alu_sel2_LATCHED <= in_alu_sel2; - reg_read_port1_addr_LATCHED <= reg_read_port1_addr; - reg_read_port2_addr_LATCHED <= reg_read_port2_addr; - reg_write_addr_LATCHED <= reg_write_addr; - Wbit_LATCHED <= Wbit; - ERROR_LATCHED <= ERROR; - HALT_LATCHED <= HALT; - next_state_LATCHED <= next_state; - memio_address_select_LATCHED <= memio_address_select; - - if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin - /* switch to microcode decoding */ - ucode_seq_addr <= ucode_seq_addr_entry; - SIMPLE_MICRO <= 1; - first_ucode <= 1; - set_initial_values <= !set_initial_values; - /*keep de_state the same and rerun decode this time with all the data from the microcode rom*/ - end else begin - if(SIMPLE_MICRO==0||first_ucode==1||owe_set_init==1)begin - first_ucode <= 0; - /* This runs at the start of the execution of an 8086 instruction */ - `ifdef DEBUG_PC_ADDRESS - $display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,IF2DE_INSTRUCTION); - `endif - `ifdef CALCULATE_IPC - new_instruction <= !new_instruction; - `endif - owe_set_init<=0; - ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end}; - VALID_INSTRUCTION_ACK <= !VALID_INSTRUCTION_ACK; - end - if(set_params)begin - set_initial_values <= !set_initial_values; - end - /* This runs at the start of each execution cycle, with microcode this is more than once per 8086 instruction */ - valid_exec_data<=!valid_exec_data; - if( SIMPLE_MICRO == 1 ) begin - ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ - if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin - /*Finished microcode*/ - SIMPLE_MICRO <= 0; - end - end - wait_exec<=1; - end -end - -always @(posedge clock) begin - case(de_state) - `DE_STATE_ENTRY:begin - if ( ( VALID_INSTRUCTION==1 || SIMPLE_MICRO == 1 ) && wait_exec==0) begin - stalled_response <= !stalled_response; - end - end - `DE_HALT:begin - end - default:begin - end - endcase -end - endmodule diff --git a/system/execute.v b/system/execute.v index 09a75e1..3979853 100644 --- a/system/execute.v +++ b/system/execute.v @@ -98,6 +98,7 @@ always @(valid_input) begin reg_write_we <= 1; biu_jump_req <= 0; use_exec_reg_addr <= 0; + next_exec<=0; end always @( set_initial_values) begin @@ -111,12 +112,11 @@ end always @(posedge reset) begin exec_state <= `EXEC_RESET; - next_exec <= 0; end `define unimpl_addressing_mode exec_state <= `EXEC_WAIT;ERROR <= `ERR_UNIMPL_ADDRESSING_MODE; -`define finished_instruction next_exec<=!next_exec; exec_state <= `EXEC_WAIT; +`define finished_instruction exec_state <= `EXEC_WAIT;next_exec<=1; always @(posedge clock) begin case (exec_state) @@ -126,13 +126,13 @@ always @(posedge clock) begin biu_jump_req <= 0; reg_write_we <= 1; exec_state <= `EXEC_WAIT; - next_exec <= 0; ERROR <= `ERR_NO_ERROR; end `EXEC_WAIT:begin reg_write_we <= 1; use_exec_reg_addr <= 0; ERROR<=`ERR_NO_ERROR; + next_exec<=1; end `EXEC_DE_LOAD_REG_TO_PARAM:begin PARAM2<=reg_read_port2_data; diff --git a/system/system.v b/system/system.v index 23251fa..a5bb934 100644 --- a/system/system.v +++ b/system/system.v @@ -165,9 +165,9 @@ end if(json_file_descriptor!=0) $fdisplay(json_file_descriptor,"],\n\"Total Cycles\":%0d,\n\"Instructions run\":%0d\n}",cycles-1,instruction_count_temp); `endif + $finish; end 2'd3: begin - $finish; end endcase end diff --git a/system/testbench.cpp b/system/testbench.cpp index 65a1a26..1509126 100644 --- a/system/testbench.cpp +++ b/system/testbench.cpp @@ -36,6 +36,7 @@ int main(int argc, char** argv) { tick(); system_state->reset=0; tick(); + tick(); system_state->reset=1; // Simulate until $finish diff --git a/system/testbench.v b/system/testbench.v index 7dc4977..f9c11b3 100644 --- a/system/testbench.v +++ b/system/testbench.v @@ -50,22 +50,26 @@ initial begin do_reset = 0; end -reg [1:0]do_reset; +reg [2:0]do_reset; always @(posedge clock) begin case(do_reset) - 2'd0:begin + 3'd0:begin do_reset<=1; end - 2'd1:begin + 3'd1:begin do_reset<=2; reset <= 0; end - 2'd2:begin + 3'd2:begin do_reset<=3; + reset <= 0; + end + 3'd3:begin + do_reset<=4; reset <= 1; end - 2'd3:begin + 3'd4:begin end endcase end