Saved a clock cycle from microcode starts and added info in decode to allow saving a cycle on almost every instruction

This commit is contained in:
(Tim) Efthimis Kritikos 2023-05-13 13:45:15 +01:00
parent 00aa828ddc
commit df342467c7
2 changed files with 47 additions and 6 deletions

View File

@ -46,8 +46,11 @@ endmodule
module decoder(
/* INPUTS */ input wire [15:0] CIR,input wire [15:0] FLAGS
/* MICROCODE */ ,output reg [`UCODE_ADDR_BITS-1:0] seq_addr_entry, input wire SIMPLE_MICRO, input wire [`UCODE_ADDR_BITS-1:0] seq_addr_input
/* OUTPUT */ ,output wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] OUTPUT
/* OUTPUT */ ,output wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] OUTPUT, output reg DEPENDS_ON_PREVIOUS
);
/* DEPENDS_ON_PREVIOUS - This encodes weather the instruction requires the previous to be finished in order to be decoded. This, for example, affects
* conditional jumps since flags are checked during decode.
*/
reg [2:0]IN_MOD;
assign OUTPUT[2:0] = IN_MOD;
@ -139,6 +142,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
next_state=`EXEC_DE_LOAD_16_PARAM;
else
next_state=`EXEC_DE_LOAD_8_PARAM;
DEPENDS_ON_PREVIOUS<=0;
`normal_instruction;
end
11'b1000_00??_101, /* SUB */
@ -182,6 +186,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
`invalid_instruction
end
endcase
DEPENDS_ON_PREVIOUS<=0;
`normal_instruction;
end
11'b1000_00??_111 : begin
@ -211,6 +216,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
in_alu_sel2=2'b00;
next_state=`EXEC_DE_LOAD_16_PARAM; /*will then call MEMIO_READ*/
end
DEPENDS_ON_PREVIOUS<=0;
`normal_instruction;
end
11'b1011_0???_??? : begin
@ -229,6 +235,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_OP=`ALU_OP_ADD;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1011_1???_??? : begin
@ -245,6 +252,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=0;
next_state=`EXEC_DE_LOAD_16_PARAM;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1000_10??_??? : begin
@ -290,6 +298,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_OP=`ALU_OP_ADD;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b0100_????_???:begin//DEC
@ -313,6 +322,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_OP=`ALU_OP_SUB;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1111_111?_00? : begin
@ -340,6 +350,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
else
next_state=`EXEC_MEMIO_READ;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1111_0100_??? : begin
@ -352,6 +363,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
MEM_OR_IO=0;
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
next_state=`EXEC_HALT;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b0011_110?_??? : begin
@ -376,6 +388,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
next_state=`EXEC_WRITE_ENTRY;
end
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b0111_????_???:begin
@ -430,6 +443,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
end
endcase
`normal_instruction;
DEPENDS_ON_PREVIOUS<=1;
memio_address_select=0;
end
11'b1110_1011_???:begin
@ -445,6 +459,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
MEM_OR_IO=0;
next_state=`EXEC_WRITE_ENTRY;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1110_1000_???:begin
@ -458,6 +473,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=2; //subtract from sp
seq_addr_entry<=`UCODE_CALL_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1100_0011_???:begin
@ -471,6 +487,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM1=2;
seq_addr_entry<=`UCODE_RET_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1010_101?_???:begin
@ -483,6 +500,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
seq_addr_entry<=`UCODE_STOS_ENTRY;
`normal_microcoded
PARAM2=(Wbit==1)?2:1;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b0101_0???_???:begin
@ -496,6 +514,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
seq_addr_entry<=`UCODE_PUSH_ENTRY;
`normal_microcoded
memio_address_select=0;
DEPENDS_ON_PREVIOUS<=0;
end
11'b1111_011?_000:begin
/* TEST - Bitwise AND affecting only flags */
@ -523,6 +542,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
endcase
OUT_MOD=3'b100;/*NULL*/
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b0101_1???_???:begin
@ -535,6 +555,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
reg_write_addr={1'b1,CIR[10:8]};
seq_addr_entry<=`UCODE_POP_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1111_1111_100:begin
@ -557,6 +578,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_OP=`ALU_OP_ADD;
OUT_MOD=3'b101;
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1100_011?_000:begin
@ -577,6 +599,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
IN_MOD=3'b011;
RM=CIR[2:0];
`normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1100_1101_???:begin
@ -594,6 +617,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=2;
seq_addr_entry<=`UCODE_INT_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
11'b1110_011?_???:begin
@ -610,6 +634,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
HALT <= 0;
PARAM1=0;
OUT_MOD={3'b000};
DEPENDS_ON_PREVIOUS<=0;
IN_MOD=3'b011;
end
11'b1100_1111_???:begin
@ -623,6 +648,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM1=2;
seq_addr_entry<=`UCODE_RET_ENTRY;
`normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0;
end
default:begin

View File

@ -112,10 +112,12 @@ reg SIMPLE_MICRO; /* output simple decodings (=0) or microcode data (=1) */
wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT;
reg [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT_sampled;
wire DE_DEPENDS_ON_PREVIOUS;
decoder decoder(
/* INPUTS */ INSTRUCTION[31:16],FLAGS,
/* MICROCODE */ ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr,
/* OUTPUT */ DE_OUTPUT
/* INPUT */ INSTRUCTION[31:16],FLAGS,
/* MICROCODE */ ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr,
/* OUTPUT */ DE_OUTPUT,DE_DEPENDS_ON_PREVIOUS
);
wire [2:0] RM;
@ -186,6 +188,8 @@ InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},instr_end);
reg [23:0] INSTRUCTION_BUFFER;
reg owe_set_init;
always @(posedge clock) begin
case(state)
`PROC_RESET:begin
@ -193,13 +197,15 @@ always @(posedge clock) begin
DE_OUTPUT_sampled <= 0;
SIMPLE_MICRO <= 0;
state <= `PROC_DE_STATE_ENTRY;
owe_set_init<=0;
end
`PROC_DE_STATE_ENTRY:begin
if(VALID_INSTRUCTION==1) begin
if(VALID_INSTRUCTION==1 || SIMPLE_MICRO == 1 ) begin
if(work==0) begin
DE_OUTPUT_sampled <= DE_OUTPUT;
if(SIMPLE_MICRO==0)begin
if(SIMPLE_MICRO==0||owe_set_init==1)begin
owe_set_init<=0;
set_initial_values<=0;
`ifdef DEBUG_PC_ADDRESS
@ -217,6 +223,15 @@ always @(posedge clock) begin
valid_exec_data <= 1;
state <= `PROC_WAIT;
end
end else begin
if( DE_DEPENDS_ON_PREVIOUS == 0)
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;
owe_set_init <= 1;
/*keep state the same and rerun decode this time with all the data from the microcode rom*/
end
end
end
end