Improved BIU performance and debug messages
This commit is contained in:
parent
da51dd6da7
commit
b7bfbd4e33
125
system/biu.v
125
system/biu.v
@ -52,10 +52,13 @@ reg [15:0] DATA_OUT;
|
||||
reg DATA_DIR;
|
||||
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*/
|
||||
reg [3:0] FIFO_end; /*exclusive*/
|
||||
`define FIFO_SIZE_BYTES 16 //$pow(2,`L1_CACHE_SIZE)
|
||||
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;
|
||||
|
||||
@ -72,16 +75,18 @@ reg jump_req;
|
||||
reg func;
|
||||
reg [19:0]INSTRUCTION_ADDRESS;
|
||||
reg [19:0]DATA_ADDRESS;
|
||||
|
||||
|
||||
assign external_address_bus= func? INSTRUCTION_ADDRESS : DATA_ADDRESS ;
|
||||
|
||||
/* Read into the FIFO */
|
||||
always @(posedge clock) begin
|
||||
if ( jump_req ) begin
|
||||
/* verilator lint_off BLKSEQ */
|
||||
FIFO_start = 4'b0;
|
||||
FIFO_start = 0;
|
||||
/* verilator lint_on BLKSEQ */
|
||||
FIFO_end <= 4'b0;
|
||||
INSTRUCTION_ADDRESS <= { 4'b0 , ADDRESS_INPUT-16'd1 };
|
||||
FIFO_end <= 0;
|
||||
INSTRUCTION_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
|
||||
INSTRUCTION_LOCATION <= ADDRESS_INPUT;
|
||||
func <= 1;
|
||||
jump_req <= 0;
|
||||
@ -96,28 +101,20 @@ always @(posedge clock) begin
|
||||
func<=0;
|
||||
DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
|
||||
DATA_DIR <= 1 ;
|
||||
VALID_INSTRUCTION <= 0;
|
||||
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) ;
|
||||
end else if ( read_request ) begin
|
||||
func<=0;
|
||||
DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
|
||||
VALID_INSTRUCTION <= 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;
|
||||
end else begin
|
||||
if((FIFO_end-FIFO_start)>4'b0011)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
|
||||
if ( FIFO_SIZE!=4'hF ) begin
|
||||
func<=1;
|
||||
biu_state <= `BIU_READ;
|
||||
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
|
||||
write <= 1;
|
||||
read <= 0;
|
||||
IOMEM <= 0;
|
||||
@ -126,18 +123,46 @@ always @(posedge clock) begin
|
||||
biu_state <= `BIU_NEXT_ACTION;
|
||||
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 ***************/
|
||||
`BIU_READ: begin
|
||||
/* 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+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
|
||||
INPUT_FIFO[FIFO_end] = external_data_bus[15:8];
|
||||
FIFO_end <= FIFO_end+4'd1;
|
||||
INSTRUCTION_ADDRESS <= INSTRUCTION_ADDRESS+1;
|
||||
end
|
||||
/* verilator lint_on BLKSEQ */
|
||||
FIFO_end <= FIFO_end+1;
|
||||
biu_state <= `BIU_NEXT_ACTION;
|
||||
read<=1;
|
||||
end
|
||||
@ -146,6 +171,10 @@ always @(posedge clock) begin
|
||||
/*************** DATA WRITE ***************/
|
||||
//TODO TODO TODO flush fifo, self modifying code
|
||||
`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;
|
||||
data_bus_output_register <= {DATA[7:0],DATA[15:8]};
|
||||
biu_state <= `BIU_PUT_UNALIGNED_PREP_NEXT;
|
||||
@ -161,10 +190,17 @@ always @(posedge clock) begin
|
||||
biu_state <= `BIU_WRITE_EXIT;
|
||||
end
|
||||
`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]};
|
||||
biu_state <= `BIU_WRITE_EXIT;
|
||||
end
|
||||
|
||||
`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;
|
||||
if(ADDRESS_INPUT[0:0]==0) begin
|
||||
BHE <= 1;
|
||||
@ -193,11 +229,21 @@ always @(posedge clock) begin
|
||||
VALID_DATA <= 0;\
|
||||
end
|
||||
`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]} ;
|
||||
read <=1;
|
||||
`finished_read
|
||||
end
|
||||
`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];
|
||||
read <=1;
|
||||
if(Wbit==1) begin
|
||||
@ -212,6 +258,9 @@ always @(posedge clock) begin
|
||||
read <=0;
|
||||
end
|
||||
`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];
|
||||
`finished_read
|
||||
read <=1;
|
||||
@ -224,7 +273,7 @@ always @(posedge clock) begin
|
||||
/* verilator lint_on BLKSEQ */
|
||||
FIFO_end <= 4'b0;
|
||||
biu_state <= `BIU_NEXT_ACTION;
|
||||
INSTRUCTION_ADDRESS <= 20'h0FFEF;
|
||||
INSTRUCTION_ADDRESS <= 20'h0FFF0;
|
||||
INSTRUCTION_LOCATION <= 16'hFFF0;
|
||||
VALID_INSTRUCTION <= 0;
|
||||
VALID_DATA <= 0;
|
||||
@ -239,6 +288,14 @@ end
|
||||
|
||||
wire [2:0] 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
|
||||
case(NEXT_POSITION)
|
||||
@ -248,17 +305,8 @@ always @( NEXT_POSITION ) begin
|
||||
FIFO_start = FIFO_start + {1'b0,Isize};
|
||||
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};;
|
||||
/* verilator lint_on BLKSEQ */
|
||||
if((FIFO_end-FIFO_start)>4'b0011)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 else begin
|
||||
VALID_INSTRUCTION <= 0;
|
||||
end
|
||||
|
||||
end
|
||||
2'b10:begin /* Jump to specific location based on register */
|
||||
jump_req <= 1;
|
||||
VALID_INSTRUCTION <= 0;
|
||||
@ -303,3 +351,20 @@ module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT );
|
||||
endcase
|
||||
end
|
||||
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
|
||||
|
@ -17,7 +17,23 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
//Runtime Verbosity
|
||||
/** Runtime Verbosity **/
|
||||
//`define DEBUG_REG_WRITES
|
||||
//`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
|
||||
|
@ -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
|
||||
//to PROC_DE_LOAD_8_PARAM
|
||||
|
||||
`define normal_instruction seq_addr_entry<=`UCODE_NO_INSTRUCTION;ERROR<=`ERR_NO_ERROR;HALT<=0;
|
||||
`define normal_microcoded 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;MEM_OR_IO=0;
|
||||
|
||||
// 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
|
||||
@ -621,6 +621,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
reg_read_port1_addr={Wbit,3'b000};
|
||||
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||
MEM_OR_IO=1;
|
||||
HALT <= 0;
|
||||
PARAM1=0;
|
||||
OUT_MOD={3'b000};
|
||||
IN_MOD=3'b011;
|
||||
|
@ -512,9 +512,6 @@ always @(posedge clock) begin
|
||||
`PROC_MEMIO_WRITE:begin
|
||||
/* 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 */
|
||||
`ifdef DEBUG_MEMORY_WRITES
|
||||
$display("Writing at %04x , %04x",reg_read_port1_data,ALU_1O);
|
||||
`endif
|
||||
|
||||
biu_write_request <= 1;
|
||||
|
||||
|
@ -42,6 +42,7 @@ assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr
|
||||
|
||||
`ifdef DEBUG_REG_WRITES
|
||||
string debug_name;
|
||||
reg [2:0] debug_address;
|
||||
`endif
|
||||
|
||||
wire write_Wbit;
|
||||
@ -81,6 +82,11 @@ always @(negedge write_port1_we) begin
|
||||
endcase
|
||||
end
|
||||
/* 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
|
||||
|
||||
end
|
||||
@ -88,11 +94,7 @@ end
|
||||
`ifdef DEBUG_REG_WRITES
|
||||
always @(posedge write_port1_we) begin
|
||||
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[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
|
||||
$display("register %%%s update to $0x%04x",debug_name,registers[debug_address]);
|
||||
end
|
||||
`endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user