Fixed a lot of "conflicting driver" issues but I had to roll back an optimisation

This commit is contained in:
(Tim) Efthimis Kritikos 2023-11-04 11:04:22 +00:00
parent c7ddf3fa9e
commit df2975fa09
7 changed files with 121 additions and 143 deletions

View File

@ -322,33 +322,33 @@ end
always @( FIFO_start or FIFO_end ) begin always @( FIFO_start or FIFO_end ) begin
if(sane==1) begin if(sane==1) begin
if(VALID_INSTRUCTION == 1 ) begin //if(VALID_INSTRUCTION == 1 ) begin
`ifdef DOUBLE_INSTRUCTION_LOAD // `ifdef DOUBLE_INSTRUCTION_LOAD
if(FIFO_SIZE>`L1_CACHE_SIZE'd3+{{`L1_CACHE_SIZE-3{1'b0}},Isize})begin // 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 // if((fifoIsize2==2) && (FIFO_SIZE > `L1_CACHE_SIZE'd1+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize}))begin
VALID_INSTRUCTION <= 1; // VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; // INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; // 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 // end else if((fifoIsize2==3) && (FIFO_SIZE > `L1_CACHE_SIZE'd2+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize}))begin
VALID_INSTRUCTION <= 1; // VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; // INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; // INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; // 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 // end else if(FIFO_SIZE>`L1_CACHE_SIZE'd3+{{`L1_CACHE_SIZE-3{1'b0}},fifoIsize})begin
VALID_INSTRUCTION <= 1; // VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start]; // INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1]; // INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; // INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2];
INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; // INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3];
end else // end else
VALID_INSTRUCTION <= 0; // VALID_INSTRUCTION <= 0;
end else begin // end else begin
VALID_INSTRUCTION <= 0; // VALID_INSTRUCTION <= 0;
end // end
`else // `else
VALID_INSTRUCTION <= 0; // VALID_INSTRUCTION <= 0;
`endif // `endif
end else begin //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]); //$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 `ifdef EARLY_VALID_INSTRUCTION
if(FIFO_start==FIFO_end) begin 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[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2];
INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3];
end end else
VALID_INSTRUCTION <= 0;
`else `else
if(FIFO_start==FIFO_end) begin if(FIFO_start==FIFO_end) begin
/*TODO: Same as on the first statment on the other side of the `ifdef */ /*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[23:16] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2]; INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd2];
INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3]; INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+`L1_CACHE_SIZE'd3];
end end else
VALID_INSTRUCTION <= 0;
`endif `endif
end //end
end end
end end

View File

@ -34,8 +34,10 @@
* for the maximum instruction size worth of bytes */ * for the maximum instruction size worth of bytes */
`define EARLY_VALID_INSTRUCTION `define EARLY_VALID_INSTRUCTION
/*********** CURRENTLY DOESN'T WORK *************/
/* Enables the ability in BIU to pre-decode two instructions, one after the other in memory*/ /* 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. /* Size is in powers of two with minimal 3.
* 3 : 8 Bytes * 3 : 8 Bytes

View File

@ -62,7 +62,9 @@ module decoder(
reg SIMPLE_MICRO; /* use simple decodings (=0) or microcode data (=1) */ reg SIMPLE_MICRO; /* use simple decodings (=0) or microcode data (=1) */
wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry; wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry;
reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr; reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr;
/* verilator lint_off UNUSEDSIGNAL */
wire DEPENDS_ON_PREVIOUS; wire DEPENDS_ON_PREVIOUS;
/* verilator lint_on UNUSEDSIGNAL */
wire set_params; wire set_params;
wire MEM_OR_IO, HALT,Wbit,memio_address_select; 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_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; wire [2:0] instr_end;
InstrSize InstrSize({IF2DE_INSTRUCTION[31:24],IF2DE_INSTRUCTION[21:19]},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; reg VALID_INSTRUCTION_lc;
always @(VALID_INSTRUCTION)begin VALID_INSTRUCTION_lc<=VALID_INSTRUCTION; end always @(VALID_INSTRUCTION)begin VALID_INSTRUCTION_lc<=VALID_INSTRUCTION; end
reg instant_response, stalled_response;
reg wait_exec;
always @(next_exec) begin always @(posedge clock)begin
de_state<=`DE_STATE_ENTRY; if(reset==0)begin
if ( VALID_INSTRUCTION_lc == 1 && DEPENDS_ON_PREVIOUS == 0 && ucode_seq_addr_entry==`UCODE_NO_INSTRUCTION) begin `ifdef CALCULATE_IPC
instant_response <= !instant_response; 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 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
end end
reg first_ucode; 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 endmodule

View File

@ -98,6 +98,7 @@ always @(valid_input) begin
reg_write_we <= 1; reg_write_we <= 1;
biu_jump_req <= 0; biu_jump_req <= 0;
use_exec_reg_addr <= 0; use_exec_reg_addr <= 0;
next_exec<=0;
end end
always @( set_initial_values) begin always @( set_initial_values) begin
@ -111,12 +112,11 @@ end
always @(posedge reset) begin always @(posedge reset) begin
exec_state <= `EXEC_RESET; exec_state <= `EXEC_RESET;
next_exec <= 0;
end end
`define unimpl_addressing_mode exec_state <= `EXEC_WAIT;ERROR <= `ERR_UNIMPL_ADDRESSING_MODE; `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 always @(posedge clock) begin
case (exec_state) case (exec_state)
@ -126,13 +126,13 @@ always @(posedge clock) begin
biu_jump_req <= 0; biu_jump_req <= 0;
reg_write_we <= 1; reg_write_we <= 1;
exec_state <= `EXEC_WAIT; exec_state <= `EXEC_WAIT;
next_exec <= 0;
ERROR <= `ERR_NO_ERROR; ERROR <= `ERR_NO_ERROR;
end end
`EXEC_WAIT:begin `EXEC_WAIT:begin
reg_write_we <= 1; reg_write_we <= 1;
use_exec_reg_addr <= 0; use_exec_reg_addr <= 0;
ERROR<=`ERR_NO_ERROR; ERROR<=`ERR_NO_ERROR;
next_exec<=1;
end end
`EXEC_DE_LOAD_REG_TO_PARAM:begin `EXEC_DE_LOAD_REG_TO_PARAM:begin
PARAM2<=reg_read_port2_data; PARAM2<=reg_read_port2_data;

View File

@ -165,9 +165,9 @@ end
if(json_file_descriptor!=0) if(json_file_descriptor!=0)
$fdisplay(json_file_descriptor,"],\n\"Total Cycles\":%0d,\n\"Instructions run\":%0d\n}",cycles-1,instruction_count_temp); $fdisplay(json_file_descriptor,"],\n\"Total Cycles\":%0d,\n\"Instructions run\":%0d\n}",cycles-1,instruction_count_temp);
`endif `endif
$finish;
end end
2'd3: begin 2'd3: begin
$finish;
end end
endcase endcase
end end

View File

@ -36,6 +36,7 @@ int main(int argc, char** argv) {
tick(); tick();
system_state->reset=0; system_state->reset=0;
tick(); tick();
tick();
system_state->reset=1; system_state->reset=1;
// Simulate until $finish // Simulate until $finish

View File

@ -50,22 +50,26 @@ initial begin
do_reset = 0; do_reset = 0;
end end
reg [1:0]do_reset; reg [2:0]do_reset;
always @(posedge clock) begin always @(posedge clock) begin
case(do_reset) case(do_reset)
2'd0:begin 3'd0:begin
do_reset<=1; do_reset<=1;
end end
2'd1:begin 3'd1:begin
do_reset<=2; do_reset<=2;
reset <= 0; reset <= 0;
end end
2'd2:begin 3'd2:begin
do_reset<=3; do_reset<=3;
reset <= 0;
end
3'd3:begin
do_reset<=4;
reset <= 1; reset <= 1;
end end
2'd3:begin 3'd4:begin
end end
endcase endcase
end end