Improved BIU performance and debug messages

This commit is contained in:
(Tim) Efthimis Kritikos 2023-05-10 04:05:56 +01:00
parent da51dd6da7
commit b7bfbd4e33
5 changed files with 125 additions and 44 deletions

View File

@ -52,10 +52,13 @@ reg [15:0] DATA_OUT;
reg DATA_DIR; reg DATA_DIR;
assign DATA=DATA_DIR ? 16'hz:DATA_OUT; assign DATA=DATA_DIR ? 16'hz:DATA_OUT;
reg [7:0] INPUT_FIFO [15:0]; //8bit fifo memory with 4bit address bus `define L1_CACHE_SIZE 4 // Don't change this! some parts of the code assume this
reg [3:0] FIFO_start; /*inclusive*/ `define FIFO_SIZE_BYTES 16 //$pow(2,`L1_CACHE_SIZE)
reg [3:0] FIFO_end; /*exclusive*/ reg [7:0] INPUT_FIFO [`FIFO_SIZE_BYTES-1:0];
reg [`L1_CACHE_SIZE-1:0] FIFO_start; /*inclusive*/
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 [3:0] biu_state;
@ -72,16 +75,18 @@ reg jump_req;
reg func; reg func;
reg [19:0]INSTRUCTION_ADDRESS; reg [19:0]INSTRUCTION_ADDRESS;
reg [19:0]DATA_ADDRESS; reg [19:0]DATA_ADDRESS;
assign external_address_bus= func? INSTRUCTION_ADDRESS : DATA_ADDRESS ; assign external_address_bus= func? INSTRUCTION_ADDRESS : DATA_ADDRESS ;
/* Read into the FIFO */ /* Read into the FIFO */
always @(posedge clock) begin always @(posedge clock) begin
if ( jump_req ) begin if ( jump_req ) begin
/* verilator lint_off BLKSEQ */ /* verilator lint_off BLKSEQ */
FIFO_start = 4'b0; FIFO_start = 0;
/* verilator lint_on BLKSEQ */ /* verilator lint_on BLKSEQ */
FIFO_end <= 4'b0; FIFO_end <= 0;
INSTRUCTION_ADDRESS <= { 4'b0 , ADDRESS_INPUT-16'd1 }; INSTRUCTION_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
INSTRUCTION_LOCATION <= ADDRESS_INPUT; INSTRUCTION_LOCATION <= ADDRESS_INPUT;
func <= 1; func <= 1;
jump_req <= 0; jump_req <= 0;
@ -96,28 +101,20 @@ always @(posedge clock) begin
func<=0; func<=0;
DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT }; DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
DATA_DIR <= 1 ; DATA_DIR <= 1 ;
VALID_INSTRUCTION <= 0;
IOMEM <= MEM_OR_IO; IOMEM <= MEM_OR_IO;
biu_state <= (Wbit==0) ? `BIU_PUT_BYTE : (ADDRESS_INPUT[0:0]?`BIU_PUT_UNALIGNED_16BIT_DATA:`BIU_PUT_ALIGNED_16BIT_DATA) ; biu_state <= (Wbit==0) ? `BIU_PUT_BYTE : (ADDRESS_INPUT[0:0]?`BIU_PUT_UNALIGNED_16BIT_DATA:`BIU_PUT_ALIGNED_16BIT_DATA) ;
end else if ( read_request ) begin end else if ( read_request ) begin
func<=0; func<=0;
DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT }; DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
VALID_INSTRUCTION <= 0;
DATA_DIR <= 0; DATA_DIR <= 0;
read <=0; IOMEM <= MEM_OR_IO;
read <= 0;
BHE <= 0;
biu_state <= (ADDRESS_INPUT[0:0])?`BIU_GET_UNALIGNED_DATA:`BIU_GET_ALIGNED_DATA; biu_state <= (ADDRESS_INPUT[0:0])?`BIU_GET_UNALIGNED_DATA:`BIU_GET_ALIGNED_DATA;
end else begin end else begin
if((FIFO_end-FIFO_start)>4'b0011)begin if ( FIFO_SIZE!=4'hF ) begin
VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+4'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+4'd2];
INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+4'd3];
end
if ( FIFO_end[3:0]+4'b0001 != FIFO_start[3:0] ) begin
func<=1; func<=1;
biu_state <= `BIU_READ; biu_state <= `BIU_READ;
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
write <= 1; write <= 1;
read <= 0; read <= 0;
IOMEM <= 0; IOMEM <= 0;
@ -126,18 +123,46 @@ always @(posedge clock) begin
biu_state <= `BIU_NEXT_ACTION; biu_state <= `BIU_NEXT_ACTION;
end end
end end
end
if((Isit1==1) && (FIFO_SIZE!=0) && `EARLY_VALID_INSTRUCTION_)begin
VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
end else if((fifoIsize==2) && (FIFO_SIZE > 1) && `EARLY_VALID_INSTRUCTION_)begin
VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+4'd1];
end else if((fifoIsize==3) && (FIFO_SIZE > 2) && `EARLY_VALID_INSTRUCTION_)begin
VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+4'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+4'd2];
end else if(FIFO_SIZE>3)begin
VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+4'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+4'd2];
INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+4'd3];
end
end
/*************** INSTRUCTION FIFO READ ***************/ /*************** INSTRUCTION FIFO READ ***************/
`BIU_READ: begin `BIU_READ: begin
/* verilator lint_off BLKSEQ */ /* verilator lint_off BLKSEQ */
if(INSTRUCTION_ADDRESS[0:0]==0)begin if(INSTRUCTION_ADDRESS[0:0]==0 && FIFO_SIZE<4'hD)begin
INPUT_FIFO[FIFO_end] = external_data_bus[7:0]; INPUT_FIFO[FIFO_end] = external_data_bus[7:0];
INPUT_FIFO[FIFO_end+4'd1] = external_data_bus[15:8];
FIFO_end <= FIFO_end+4'd2;
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+20'd2;
end else if(INSTRUCTION_ADDRESS[0:0]==0)begin
INPUT_FIFO[FIFO_end] = external_data_bus[7:0];
FIFO_end <= FIFO_end+4'd1;
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
end else begin end else begin
INPUT_FIFO[FIFO_end] = external_data_bus[15:8]; INPUT_FIFO[FIFO_end] = external_data_bus[15:8];
FIFO_end <= FIFO_end+4'd1;
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
end end
/* verilator lint_on BLKSEQ */ /* verilator lint_on BLKSEQ */
FIFO_end <= FIFO_end+1;
biu_state <= `BIU_NEXT_ACTION; biu_state <= `BIU_NEXT_ACTION;
read<=1; read<=1;
end end
@ -146,6 +171,10 @@ always @(posedge clock) begin
/*************** DATA WRITE ***************/ /*************** DATA WRITE ***************/
//TODO TODO TODO flush fifo, self modifying code //TODO TODO TODO flush fifo, self modifying code
`BIU_PUT_UNALIGNED_16BIT_DATA:begin `BIU_PUT_UNALIGNED_16BIT_DATA:begin
//TODO Put that in the previous stage, save a clock cycle
`ifdef DEBUG_DATA_READ_WRITES
$display("Writing 16bit %04x at %04x",DATA,DATA_ADDRESS);
`endif
BHE <= 0; BHE <= 0;
data_bus_output_register <= {DATA[7:0],DATA[15:8]}; data_bus_output_register <= {DATA[7:0],DATA[15:8]};
biu_state <= `BIU_PUT_UNALIGNED_PREP_NEXT; biu_state <= `BIU_PUT_UNALIGNED_PREP_NEXT;
@ -161,10 +190,17 @@ always @(posedge clock) begin
biu_state <= `BIU_WRITE_EXIT; biu_state <= `BIU_WRITE_EXIT;
end end
`BIU_PUT_ALIGNED_16BIT_DATA:begin `BIU_PUT_ALIGNED_16BIT_DATA:begin
`ifdef DEBUG_DATA_READ_WRITES
$display("Writing 16bit %04x at %04x",DATA,DATA_ADDRESS);
`endif
data_bus_output_register <= {DATA[15:8],DATA[7:0]}; data_bus_output_register <= {DATA[15:8],DATA[7:0]};
biu_state <= `BIU_WRITE_EXIT; biu_state <= `BIU_WRITE_EXIT;
end end
`BIU_PUT_BYTE:begin `BIU_PUT_BYTE:begin
`ifdef DEBUG_DATA_READ_WRITES
$display("Writing 8bit %02x at %04x",DATA[7:0],DATA_ADDRESS);
`endif
biu_state <= `BIU_WRITE_EXIT; biu_state <= `BIU_WRITE_EXIT;
if(ADDRESS_INPUT[0:0]==0) begin if(ADDRESS_INPUT[0:0]==0) begin
BHE <= 1; BHE <= 1;
@ -193,11 +229,21 @@ always @(posedge clock) begin
VALID_DATA <= 0;\ VALID_DATA <= 0;\
end end
`BIU_GET_ALIGNED_DATA:begin `BIU_GET_ALIGNED_DATA:begin
`ifdef DEBUG_DATA_READ_WRITES
if(Wbit==1)
$display("Reading 16bit %04x from %04x",external_data_bus,DATA_ADDRESS);
else
$display("Reading 8bit %02x from %04x",external_data_bus[7:0],DATA_ADDRESS);
`endif
DATA_OUT <= (Wbit==1)? external_data_bus : {8'b0,external_data_bus[7:0]} ; DATA_OUT <= (Wbit==1)? external_data_bus : {8'b0,external_data_bus[7:0]} ;
read <=1; read <=1;
`finished_read `finished_read
end end
`BIU_GET_UNALIGNED_DATA:begin `BIU_GET_UNALIGNED_DATA:begin
`ifdef DEBUG_DATA_READ_WRITES
if(Wbit==0)
$display("Reading 8bit %02x from %04x",external_data_bus[15:8],DATA_ADDRESS);
`endif
DATA_OUT[7:0] <= external_data_bus[15:8]; DATA_OUT[7:0] <= external_data_bus[15:8];
read <=1; read <=1;
if(Wbit==1) begin if(Wbit==1) begin
@ -212,6 +258,9 @@ always @(posedge clock) begin
read <=0; read <=0;
end end
`BIU_GET_SECOND_BYTE1:begin `BIU_GET_SECOND_BYTE1:begin
`ifdef DEBUG_DATA_READ_WRITES
$display("Reading 16bit %02x from %04x",{external_data_bus[7:0],DATA_OUT[7:0]},DATA_ADDRESS-1);//read started a byte earlier
`endif
DATA_OUT[15:8] <= external_data_bus[7:0]; DATA_OUT[15:8] <= external_data_bus[7:0];
`finished_read `finished_read
read <=1; read <=1;
@ -224,7 +273,7 @@ always @(posedge clock) begin
/* verilator lint_on BLKSEQ */ /* verilator lint_on BLKSEQ */
FIFO_end <= 4'b0; FIFO_end <= 4'b0;
biu_state <= `BIU_NEXT_ACTION; biu_state <= `BIU_NEXT_ACTION;
INSTRUCTION_ADDRESS <= 20'h0FFEF; INSTRUCTION_ADDRESS <= 20'h0FFF0;
INSTRUCTION_LOCATION <= 16'hFFF0; INSTRUCTION_LOCATION <= 16'hFFF0;
VALID_INSTRUCTION <= 0; VALID_INSTRUCTION <= 0;
VALID_DATA <= 0; VALID_DATA <= 0;
@ -239,6 +288,14 @@ end
wire [2:0] Isize; wire [2:0] Isize;
InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},Isize); InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},Isize);
/* verilator lint_off UNDRIVEN */
wire [2:0] fifoIsize;
wire Isit1;
/* verilator lint_on UNDRIVEN */
`ifdef EARLY_VALID_INSTRUCTION
InstrSize fifoInstrSize({INPUT_FIFO[FIFO_start][7:0],INPUT_FIFO[FIFO_start][5:3]},fifoIsize);
Is1 Is1(INPUT_FIFO[FIFO_start][7:0],Isit1);
`endif
always @( NEXT_POSITION ) begin always @( NEXT_POSITION ) begin
case(NEXT_POSITION) case(NEXT_POSITION)
@ -248,16 +305,7 @@ always @( NEXT_POSITION ) begin
FIFO_start = FIFO_start + {1'b0,Isize}; FIFO_start = FIFO_start + {1'b0,Isize};
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};; INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};;
/* verilator lint_on BLKSEQ */ /* verilator lint_on BLKSEQ */
if((FIFO_end-FIFO_start)>4'b0011)begin VALID_INSTRUCTION <= 0;
VALID_INSTRUCTION <= 1;
INSTRUCTION[31:24] <= INPUT_FIFO[FIFO_start];
INSTRUCTION[23:16] <= INPUT_FIFO[FIFO_start+4'd1];
INSTRUCTION[15: 8] <= INPUT_FIFO[FIFO_start+4'd2];
INSTRUCTION[ 7: 0] <= INPUT_FIFO[FIFO_start+4'd3];
end else begin
VALID_INSTRUCTION <= 0;
end
end end
2'b10:begin /* Jump to specific location based on register */ 2'b10:begin /* Jump to specific location based on register */
jump_req <= 1; jump_req <= 1;
@ -303,3 +351,20 @@ module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT );
endcase endcase
end end
endmodule endmodule
`ifdef EARLY_VALID_INSTRUCTION
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
endcase
end
endmodule
`endif

View File

@ -17,7 +17,23 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
//Runtime Verbosity /** Runtime Verbosity **/
//`define DEBUG_REG_WRITES //`define DEBUG_REG_WRITES
//`define DEBUG_PC_ADDRESS //`define DEBUG_PC_ADDRESS
//`define DEBUG_MEMORY_WRITES //`define DEBUG_DATA_READ_WRITES
/** Optimisations **/
/* Enables the ability to check if an instruction in the input
* buffer is completed and mark it ready instead of always waiting
* for the maximum instruction size worth of bytes */
`define EARLY_VALID_INSTRUCTION
/* Internal */
`ifdef EARLY_VALID_INSTRUCTION
`define EARLY_VALID_INSTRUCTION_ 1
`else
`define EARLY_VALID_INSTRUCTION_ 0
`endif

View File

@ -85,8 +85,8 @@ microcode ucode(seq_addr_input,ucode_data);
//opcode_size=0 would be to set PARAM1 here instead of sending execution over //opcode_size=0 would be to set PARAM1 here instead of sending execution over
//to PROC_DE_LOAD_8_PARAM //to PROC_DE_LOAD_8_PARAM
`define normal_instruction seq_addr_entry<=`UCODE_NO_INSTRUCTION;ERROR<=`ERR_NO_ERROR;HALT<=0; `define normal_instruction seq_addr_entry<=`UCODE_NO_INSTRUCTION;ERROR<=`ERR_NO_ERROR;HALT<=0;MEM_OR_IO=0;
`define normal_microcoded ERROR<=`ERR_NO_ERROR;HALT<=0; `define normal_microcoded ERROR<=`ERR_NO_ERROR;HALT<=0;MEM_OR_IO=0;
// I use blocking for basically putting names on the different fields of CIR and // I use blocking for basically putting names on the different fields of CIR and
// then branching off of that instead of the raw bits. otherwise the code // then branching off of that instead of the raw bits. otherwise the code
@ -621,6 +621,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
reg_read_port1_addr={Wbit,3'b000}; reg_read_port1_addr={Wbit,3'b000};
next_state=`PROC_DE_LOAD_8_PARAM; next_state=`PROC_DE_LOAD_8_PARAM;
MEM_OR_IO=1; MEM_OR_IO=1;
HALT <= 0;
PARAM1=0; PARAM1=0;
OUT_MOD={3'b000}; OUT_MOD={3'b000};
IN_MOD=3'b011; IN_MOD=3'b011;

View File

@ -512,9 +512,6 @@ always @(posedge clock) begin
`PROC_MEMIO_WRITE:begin `PROC_MEMIO_WRITE:begin
/* if memio_address_select == 0 ADDRESS: reg_read_port1_data DATA:ALU1_O */ /* if memio_address_select == 0 ADDRESS: reg_read_port1_data DATA:ALU1_O */
/* if memio_address_select == 1 ADDRESS: ALU1_O DATA: reg_read_port1_data */ /* if memio_address_select == 1 ADDRESS: ALU1_O DATA: reg_read_port1_data */
`ifdef DEBUG_MEMORY_WRITES
$display("Writing at %04x , %04x",reg_read_port1_data,ALU_1O);
`endif
biu_write_request <= 1; biu_write_request <= 1;

View File

@ -42,6 +42,7 @@ assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr
`ifdef DEBUG_REG_WRITES `ifdef DEBUG_REG_WRITES
string debug_name; string debug_name;
reg [2:0] debug_address;
`endif `endif
wire write_Wbit; wire write_Wbit;
@ -81,6 +82,11 @@ always @(negedge write_port1_we) begin
endcase endcase
end end
/* verilator lint_on BLKSEQ */ /* verilator lint_on BLKSEQ */
if (write_Wbit)
debug_address<=write_port1_addr[2:0];
else
debug_address<={1'b0,write_port1_addr[1:0]};
`endif `endif
end end
@ -88,11 +94,7 @@ end
`ifdef DEBUG_REG_WRITES `ifdef DEBUG_REG_WRITES
always @(posedge write_port1_we) begin always @(posedge write_port1_we) begin
if ( debug_name != "" ) /*At the start this triggers for some reason */ if ( debug_name != "" ) /*At the start this triggers for some reason */
if (write_Wbit)begin $display("register %%%s update to $0x%04x",debug_name,registers[debug_address]);
$display("register %%%s update to $0x%04x",debug_name,registers[write_port1_addr[2:0]]);
end else begin
$display("register %%%s update to $0x%04x",debug_name,registers[{1'b0,write_port1_addr[1:0]}]);
end
end end
`endif `endif