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( module decoder(
/* INPUTS */ input wire [15:0] CIR,input wire [15:0] FLAGS /* 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 /* 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; reg [2:0]IN_MOD;
assign OUTPUT[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; next_state=`EXEC_DE_LOAD_16_PARAM;
else else
next_state=`EXEC_DE_LOAD_8_PARAM; next_state=`EXEC_DE_LOAD_8_PARAM;
DEPENDS_ON_PREVIOUS<=0;
`normal_instruction; `normal_instruction;
end end
11'b1000_00??_101, /* SUB */ 11'b1000_00??_101, /* SUB */
@ -182,6 +186,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
`invalid_instruction `invalid_instruction
end end
endcase endcase
DEPENDS_ON_PREVIOUS<=0;
`normal_instruction; `normal_instruction;
end end
11'b1000_00??_111 : begin 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; in_alu_sel2=2'b00;
next_state=`EXEC_DE_LOAD_16_PARAM; /*will then call MEMIO_READ*/ next_state=`EXEC_DE_LOAD_16_PARAM; /*will then call MEMIO_READ*/
end end
DEPENDS_ON_PREVIOUS<=0;
`normal_instruction; `normal_instruction;
end end
11'b1011_0???_??? : begin 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; ALU_OP=`ALU_OP_ADD;
next_state=`EXEC_WRITE_ENTRY; next_state=`EXEC_WRITE_ENTRY;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1011_1???_??? : begin 11'b1011_1???_??? : begin
@ -245,6 +252,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=0; PARAM2=0;
next_state=`EXEC_DE_LOAD_16_PARAM; next_state=`EXEC_DE_LOAD_16_PARAM;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1000_10??_??? : begin 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; ALU_OP=`ALU_OP_ADD;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b0100_????_???:begin//DEC 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; ALU_OP=`ALU_OP_SUB;
next_state=`EXEC_WRITE_ENTRY; next_state=`EXEC_WRITE_ENTRY;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1111_111?_00? : begin 11'b1111_111?_00? : begin
@ -340,6 +350,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
else else
next_state=`EXEC_MEMIO_READ; next_state=`EXEC_MEMIO_READ;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1111_0100_??? : begin 11'b1111_0100_??? : begin
@ -352,6 +363,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
MEM_OR_IO=0; MEM_OR_IO=0;
seq_addr_entry<=`UCODE_NO_INSTRUCTION; seq_addr_entry<=`UCODE_NO_INSTRUCTION;
next_state=`EXEC_HALT; next_state=`EXEC_HALT;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b0011_110?_??? : begin 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; next_state=`EXEC_WRITE_ENTRY;
end end
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b0111_????_???:begin 11'b0111_????_???:begin
@ -430,6 +443,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
end end
endcase endcase
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=1;
memio_address_select=0; memio_address_select=0;
end end
11'b1110_1011_???:begin 11'b1110_1011_???:begin
@ -445,6 +459,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
MEM_OR_IO=0; MEM_OR_IO=0;
next_state=`EXEC_WRITE_ENTRY; next_state=`EXEC_WRITE_ENTRY;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1110_1000_???:begin 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 PARAM2=2; //subtract from sp
seq_addr_entry<=`UCODE_CALL_ENTRY; seq_addr_entry<=`UCODE_CALL_ENTRY;
`normal_microcoded `normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1100_0011_???:begin 11'b1100_0011_???:begin
@ -471,6 +487,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM1=2; PARAM1=2;
seq_addr_entry<=`UCODE_RET_ENTRY; seq_addr_entry<=`UCODE_RET_ENTRY;
`normal_microcoded `normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1010_101?_???:begin 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; seq_addr_entry<=`UCODE_STOS_ENTRY;
`normal_microcoded `normal_microcoded
PARAM2=(Wbit==1)?2:1; PARAM2=(Wbit==1)?2:1;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b0101_0???_???:begin 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; seq_addr_entry<=`UCODE_PUSH_ENTRY;
`normal_microcoded `normal_microcoded
memio_address_select=0; memio_address_select=0;
DEPENDS_ON_PREVIOUS<=0;
end end
11'b1111_011?_000:begin 11'b1111_011?_000:begin
/* TEST - Bitwise AND affecting only flags */ /* TEST - Bitwise AND affecting only flags */
@ -523,6 +542,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
endcase endcase
OUT_MOD=3'b100;/*NULL*/ OUT_MOD=3'b100;/*NULL*/
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b0101_1???_???:begin 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]}; reg_write_addr={1'b1,CIR[10:8]};
seq_addr_entry<=`UCODE_POP_ENTRY; seq_addr_entry<=`UCODE_POP_ENTRY;
`normal_microcoded `normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1111_1111_100:begin 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; ALU_OP=`ALU_OP_ADD;
OUT_MOD=3'b101; OUT_MOD=3'b101;
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1100_011?_000:begin 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; IN_MOD=3'b011;
RM=CIR[2:0]; RM=CIR[2:0];
`normal_instruction; `normal_instruction;
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1100_1101_???:begin 11'b1100_1101_???:begin
@ -594,6 +617,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=2; PARAM2=2;
seq_addr_entry<=`UCODE_INT_ENTRY; seq_addr_entry<=`UCODE_INT_ENTRY;
`normal_microcoded `normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
11'b1110_011?_???:begin 11'b1110_011?_???:begin
@ -610,6 +634,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
HALT <= 0; HALT <= 0;
PARAM1=0; PARAM1=0;
OUT_MOD={3'b000}; OUT_MOD={3'b000};
DEPENDS_ON_PREVIOUS<=0;
IN_MOD=3'b011; IN_MOD=3'b011;
end end
11'b1100_1111_???:begin 11'b1100_1111_???:begin
@ -623,6 +648,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM1=2; PARAM1=2;
seq_addr_entry<=`UCODE_RET_ENTRY; seq_addr_entry<=`UCODE_RET_ENTRY;
`normal_microcoded `normal_microcoded
DEPENDS_ON_PREVIOUS<=0;
memio_address_select=0; memio_address_select=0;
end end
default:begin 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; wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT;
reg [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT_sampled; reg [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT_sampled;
wire DE_DEPENDS_ON_PREVIOUS;
decoder decoder( decoder decoder(
/* INPUTS */ INSTRUCTION[31:16],FLAGS, /* INPUT */ INSTRUCTION[31:16],FLAGS,
/* MICROCODE */ ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr, /* MICROCODE */ ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr,
/* OUTPUT */ DE_OUTPUT /* OUTPUT */ DE_OUTPUT,DE_DEPENDS_ON_PREVIOUS
); );
wire [2:0] RM; wire [2:0] RM;
@ -186,6 +188,8 @@ InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},instr_end);
reg [23:0] INSTRUCTION_BUFFER; reg [23:0] INSTRUCTION_BUFFER;
reg owe_set_init;
always @(posedge clock) begin always @(posedge clock) begin
case(state) case(state)
`PROC_RESET:begin `PROC_RESET:begin
@ -193,13 +197,15 @@ always @(posedge clock) begin
DE_OUTPUT_sampled <= 0; DE_OUTPUT_sampled <= 0;
SIMPLE_MICRO <= 0; SIMPLE_MICRO <= 0;
state <= `PROC_DE_STATE_ENTRY; state <= `PROC_DE_STATE_ENTRY;
owe_set_init<=0;
end end
`PROC_DE_STATE_ENTRY:begin `PROC_DE_STATE_ENTRY:begin
if(VALID_INSTRUCTION==1) begin if(VALID_INSTRUCTION==1 || SIMPLE_MICRO == 1 ) begin
if(work==0) begin if(work==0) begin
DE_OUTPUT_sampled <= DE_OUTPUT; 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; set_initial_values<=0;
`ifdef DEBUG_PC_ADDRESS `ifdef DEBUG_PC_ADDRESS
@ -217,6 +223,15 @@ always @(posedge clock) begin
valid_exec_data <= 1; valid_exec_data <= 1;
state <= `PROC_WAIT; state <= `PROC_WAIT;
end 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 end
end end