diff --git a/README.md b/README.md index 6ee3c5b..9281f72 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A CPU that aims to be binary compatible with the 8086 and with as many optimisat * [X] Is Turing complete * [ ] Can boot up MS-DOS / FreeDOS * [ ] Is completely binary compatible - * [ ] Is pipelined + * [X] Is pipelined * [ ] Is Out of Order * [ ] Is superscalar * [ ] Has been successfully synthesized diff --git a/gtkwave_savefile.gtkw b/gtkwave_savefile.gtkw index 68b2324..da2c35d 100644 --- a/gtkwave_savefile.gtkw +++ b/gtkwave_savefile.gtkw @@ -1,42 +1,63 @@ [*] [*] GTKWave Analyzer v3.3.111 (w)1999-2020 BSI -[*] Thu May 11 08:14:36 2023 +[*] Sat May 13 03:32:49 2023 [*] -[dumpfile] "/home/user/9086/system/boot_code.fst" -[dumpfile_mtime] "Thu May 11 08:13:23 2023" -[dumpfile_size] 2215158 -[savefile] "/home/user/9086/gtkwave_savefile.gtkw" -[timestart] 29810000000 -[size] 1236 993 +[dumpfile] "/home/user/9086_take_two/system/boot_code.fst" +[dumpfile_mtime] "Sat May 13 03:30:49 2023" +[dumpfile_size] 8561 +[savefile] "/home/user/9086_take_two/gtkwave_savefile.gtkw" +[timestart] 102870000000 +[size] 1140 993 [pos] -1 -1 -*-31.895050 34640000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-33.395050 121840000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] TOP. [treeopen] TOP.system. [treeopen] TOP.system.p. [treeopen] TOP.system.p.BIU. +[treeopen] TOP.system.p.decoder. [treeopen] TOP.system.p.execute_unit. [sst_width] 263 -[signals_width] 293 +[signals_width] 231 [sst_expanded] 1 -[sst_vpaned_height] 295 +[sst_vpaned_height] 296 @28 TOP.system.clock TOP.system.reset @22 TOP.system.address_bus[19:0] TOP.system.data_bus[15:0] -TOP.system.p.BIU.biu_state[3:0] @28 TOP.system.p.read TOP.system.p.write -TOP.system.IOMEM +@200 +- +@28 +TOP.system.p.BIU.VALID_INSTRUCTION +TOP.system.p.valid_exec_data +@22 +TOP.system.p.execute_unit.INSTRUCTION_BUFFER[23:0] +TOP.system.p.BIU.biu_state[3:0] +@28 +TOP.system.p.execute_unit.exec_state[3:0] +TOP.system.p.BIU.write_request +@29 +TOP.system.p.BIU.read_request +@28 +TOP.system.p.SIMPLE_MICRO +@22 +TOP.system.p.ucode_seq_addr[4:0] +@28 +TOP.system.p.execute_unit.biu_jump_req +TOP.system.p.execute_unit.stall +@200 +- +@28 TOP.system.p.ERROR[2:0] +TOP.system.IOMEM TOP.system.p.HALT @22 TOP.system.p.BIU.INSTRUCTION[31:0] -@28 -TOP.system.p.BIU.VALID_INSTRUCTION -@22 +TOP.system.p.decoder.seq_addr_entry[4:0] TOP.system.p.BIU.FIFO_end[3:0] TOP.system.p.BIU.FIFO_start[3:0] TOP.system.p.BIU.INPUT_FIFO[0][7:0] @@ -55,13 +76,5 @@ TOP.system.p.BIU.INPUT_FIFO[12][7:0] TOP.system.p.BIU.INPUT_FIFO[13][7:0] TOP.system.p.BIU.INPUT_FIFO[14][7:0] TOP.system.p.BIU.INPUT_FIFO[15][7:0] -TOP.system.p.ucode_seq_addr[4:0] -@28 -TOP.system.p.execute_unit.exec_state[3:0] -TOP.system.p.state[2:0] -TOP.system.p.valid_exec_data -TOP.system.p.reg_write_we -@29 -TOP.system.p.SIMPLE_MICRO [pattern_trace] 1 [pattern_trace] 0 diff --git a/system/biu.v b/system/biu.v index 7e11619..beb0a5a 100644 --- a/system/biu.v +++ b/system/biu.v @@ -42,7 +42,7 @@ module BIU ( /* */ inout [15:0] external_data_bus,output reg read, output reg write,output reg BHE,output reg IOMEM, /* Internal */ output reg [31:0] INSTRUCTION, output reg VALID_INSTRUCTION, output reg [15:0] INSTRUCTION_LOCATION, input jump_req, /* */ input[15:0] ADDRESS_INPUT, inout [15:0] DATA, input write_request, input read_request, input Wbit, output reg VALID_DATA, input MEM_OR_IO, -/* */ input [`PROC_STATE_BITS-1:0] proc_state, input SIMPLE_MICRO +/* */ input [`PROC_STATE_BITS-1:0] proc_state, input SIMPLE_MICRO,input stall ); reg [15:0] data_bus_output_register; @@ -63,6 +63,7 @@ reg [3:0] biu_state; always @(negedge reset) begin biu_state <= `BIU_HALT; + write <= 1; end always @(posedge reset) begin biu_state <= `BIU_RESET; @@ -120,24 +121,26 @@ always @(posedge clock) begin 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]; + if ( !stall ) begin + 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 end diff --git a/system/execute.v b/system/execute.v index 01189d6..866f883 100644 --- a/system/execute.v +++ b/system/execute.v @@ -20,7 +20,7 @@ module execute_unit ( /* GENERAL */ input clock, input reset ,input Wbit, input Sbit, input opcode_size,input [23:0] INSTRUCTION_BUFFER,input valid_input /* */ ,input [2:0] IN_MOD, input [2:0] OUT_MOD, input memio_address_select, input [15:0] ProgCount, input [2:0] RM, output reg [`ERROR_BITS-1:0] ERROR , input write /*TODO: REMOVE!!*/ - /* */ ,input set_initial_values + /* */ ,input set_initial_values,output stall /* PARAM */ ,input [15:0] PARAM1_INIT, input [15:0] PARAM2_INIT /* STATE CONTROL */ ,output [`EXEC_STATE_BITS-1:0] _exec_state_, input [`EXEC_STATE_BITS-1:0] init_state /* ALU CONTROL */ ,input [1:0] in_alu_sel1, input [1:0] in_alu_sel2, input [`ALU_OP_BITS-1:0] ALU_OP, output [15:0] _ALU_O_ @@ -29,6 +29,8 @@ module execute_unit ( /* BIU */ ,output reg [15:0] BIU_ADDRESS_INPUT,output reg biu_write_request, output reg biu_read_request, input BIU_VALID_DATA, input [15:0] BIU_DATA, output reg biu_data_direction, output reg biu_jump_req ); +assign stall = work&valid_input; + assign _exec_state_ = exec_state; assign _ALU_O_ = ALU_O; @@ -70,7 +72,10 @@ ALU ALU1( /*############ Execute logic ########################################################## */ always @(posedge valid_input) begin - exec_state <= init_state; + if(work == 0)begin + exec_state <= init_state; + work <= 1; + end end always @(negedge set_initial_values) begin @@ -87,9 +92,12 @@ always @(posedge reset) begin end `define unimpl_addressing_mode exec_state <= `EXEC_DONE;ERROR <= `ERR_UNIMPL_ADDRESSING_MODE; + +reg work; always @(posedge clock) begin case (exec_state) `EXEC_RESET: begin + work <= 0; biu_write_request <= 0; biu_read_request <= 0; biu_data_direction <= 0; @@ -99,11 +107,13 @@ always @(posedge clock) begin ERROR <= `ERR_NO_ERROR; end `EXEC_DONE:begin + work <= 0; reg_write_we <= 1; biu_jump_req <= 0; use_exec_reg_addr <= 0; end `EXEC_DE_LOAD_REG_TO_PARAM:begin + work <= 1; PARAM2<=reg_read_port2_data; case(IN_MOD) 3'b000,3'b001,3'b010: exec_state <= `EXEC_MEMIO_READ; @@ -111,6 +121,7 @@ always @(posedge clock) begin endcase end `EXEC_DE_LOAD_8_PARAM:begin + work <= 1; if(opcode_size==0)begin if({Sbit,Wbit}==2'b11)begin /*signed "16bit" read*/ @@ -136,6 +147,7 @@ always @(posedge clock) begin endcase end `EXEC_DE_LOAD_16_PARAM:begin + work <= 1; if(opcode_size==0)begin PARAM1[7:0] <= INSTRUCTION_BUFFER[23:16]; PARAM1[15:8] <= INSTRUCTION_BUFFER[15:8]; @@ -149,6 +161,7 @@ always @(posedge clock) begin endcase end `EXEC_MEMIO_READ:begin + work <= 1; /*Decode MOD R/M, read the data and place it to PARAM1*/ case (IN_MOD) 3'b000, @@ -210,6 +223,7 @@ always @(posedge clock) begin endcase end `EXEC_MEMIO_READ_SETADDR:begin + work <= 1; if(memio_address_select==0) BIU_ADDRESS_INPUT <= reg_read_port1_data[15:0]; else @@ -226,10 +240,12 @@ always @(posedge clock) begin end end `EXEC_NEXT_INSTRUCTION:begin + work <= 1; /*necessary for biu to see we went on another state from decode to give us a new instruction*/ exec_state <= `EXEC_DONE; end `EXEC_WRITE_ENTRY:begin + work <= 1; FLAGS[7:0] <= ALU_FLAGS[7:0]; case(OUT_MOD) 3'b000, @@ -306,6 +322,7 @@ always @(posedge clock) begin endcase end `EXEC_MEMIO_WRITE:begin + work <= 1; /* 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 */ diff --git a/system/processor.v b/system/processor.v index 4378ec8..c7867be 100644 --- a/system/processor.v +++ b/system/processor.v @@ -72,10 +72,11 @@ assign OUT_MOD=DE_OUTPUT_sampled[49:47]; wire [`ALU_OP_BITS-1:0] ALU_OP; assign ALU_OP = DE_OUTPUT_sampled[42:40]; +wire stall; execute_unit execute_unit ( /* GENERAL */ clock, reset, Wbit, Sbit, opcode_size, INSTRUCTION_BUFFER,valid_exec_data /* */ ,IN_MOD, OUT_MOD,memio_address_select, ProgCount, RM, EXEC_ERROR, write - /* */ ,set_initial_values + /* */ ,set_initial_values,stall /* PARAM */ ,PARAM1_INIT,PARAM2_INIT /* STATE CONTROL */ ,exec_state, next_state /* ALU CONTROL */ ,in_alu_sel1, in_alu_sel2, ALU_OP, ALU_O @@ -97,8 +98,9 @@ BIU BIU( /* */ ,external_data_bus,read,write,BHE,IOMEM /* Internal */ ,INSTRUCTION,VALID_INSTRUCTION,INSTRUCTION_LOCATION,biu_jump_req /* */ ,BIU_ADDRESS_INPUT,BIU_DATA,biu_write_request,biu_read_request,Wbit,BIU_VALID_DATA,MEM_OR_IO - /* */ ,state,SIMPLE_MICRO + /* */ ,state,SIMPLE_MICRO,stall ); + assign BIU_DATA= biu_data_direction ? 16'hz : (memio_address_select ? reg_read_port1_data : ALU_O); /*############ Decoder ########################################################## */ @@ -193,34 +195,34 @@ always @(posedge clock) begin state <= `PROC_DE_STATE_ENTRY; end `PROC_DE_STATE_ENTRY:begin - if(VALID_INSTRUCTION==1) begin + if (!stall) begin + if(VALID_INSTRUCTION==1) begin + DE_OUTPUT_sampled <= DE_OUTPUT; - DE_OUTPUT_sampled <= DE_OUTPUT; + if(SIMPLE_MICRO==0)begin + set_initial_values<=0; - if(SIMPLE_MICRO==0)begin - set_initial_values<=0; - - `ifdef DEBUG_PC_ADDRESS - $display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,INSTRUCTION); - `endif - ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end}; - INSTRUCTION_BUFFER<=INSTRUCTION[23:0]; - end - 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; - /*keep state the same and rerun decode this time with all the data from the microcode rom*/ - end else begin - valid_exec_data <= 1; - state <= `PROC_WAIT; + `ifdef DEBUG_PC_ADDRESS + $display("Running command at %04x (%08x)",INSTRUCTION_LOCATION,INSTRUCTION); + `endif + ProgCount <= INSTRUCTION_LOCATION+{12'b0,instr_end}; + INSTRUCTION_BUFFER<=INSTRUCTION[23:0]; + end + 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; + /*keep state the same and rerun decode this time with all the data from the microcode rom*/ + end else begin + valid_exec_data <= 1; + state <= `PROC_WAIT; + end end end end `PROC_WAIT:begin - set_initial_values<=1; - if( exec_state == `EXEC_DONE ) begin - FLAGS <= {8'b0,EXEC_FLAGS}; //TODO: don't set all of them all the time! + if(!stall) begin + set_initial_values<=1; valid_exec_data<=0; state <= `PROC_DE_STATE_ENTRY; if( SIMPLE_MICRO == 1 ) begin @@ -239,4 +241,9 @@ always @(posedge clock) begin endcase end +always @(exec_state) begin + if(exec_state == `EXEC_DONE) + FLAGS <= {8'b0,EXEC_FLAGS}; //TODO: don't set all of them all the time! +end + endmodule