diff --git a/system/biu.v b/system/biu.v index e4f4939..356fc6b 100644 --- a/system/biu.v +++ b/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 - 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,16 +305,7 @@ 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 - + VALID_INSTRUCTION <= 0; end 2'b10:begin /* Jump to specific location based on register */ jump_req <= 1; @@ -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 diff --git a/system/config.v b/system/config.v index eb0c66a..1d8feaa 100644 --- a/system/config.v +++ b/system/config.v @@ -17,7 +17,23 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -//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 diff --git a/system/decoder.v b/system/decoder.v index a8c620a..aacec12 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -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; diff --git a/system/processor.v b/system/processor.v index 15bc2f6..e0bbfda 100644 --- a/system/processor.v +++ b/system/processor.v @@ -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; diff --git a/system/registers.v b/system/registers.v index 6debdf0..a1ca666 100644 --- a/system/registers.v +++ b/system/registers.v @@ -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