diff --git a/README.md b/README.md index 5e1fa30..6ee3c5b 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ A CPU that aims to be binary compatible with the 8086 and with as many optimisat Both Verilator and Icarus Verilog can be used for simulation. You can select which one you want with the SIM variable on [common.mk](./common.mk) Specifically this list shows the software needed and the versions used during development (other versions should work as well) -* Icarus Verilog : version 11.0 OR **(preferred)** Verilator : 5.006 +* Icarus Verilog : version 11.0 OR **(preferred)** Verilator : 5.008 * bin86 : 0.16.21 * GNU Make : 4.4.1 * xxd : 2022-01-14 -* POSIX coreutils : GNU coreutils 9.1 +* POSIX coreutils : GNU coreutils 9.3 After that you can run `make` on the top level directory and it should build everything and start the simulation diff --git a/system/biu.v b/system/biu.v index 90ba941..ceda3c5 100644 --- a/system/biu.v +++ b/system/biu.v @@ -1,4 +1,4 @@ -/* processor.v - implementation of the 9086 bus interface unit. The logic that +/* biu.v - implementation of the 9086 bus interface unit. The logic that controls all external bus functions This file is part of the 9086 project. @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -//IOMEM: 1=IO 0=MEM +`include "config.v" `define BIU_HALT 4'b0000 `define BIU_NEXT_ACTION 4'b0001 @@ -38,11 +38,11 @@ `define BIU_GET_SECOND_BYTE1 4'b1110 module BIU ( -/*outside world*/ input clock, input reset, output reg [19:0] external_address_bus, -/* */ 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 +/* Outside world */ input clock, input reset, output reg [19:0] external_address_bus, +/* */ 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 ); reg [15:0] data_bus_output_register; @@ -52,12 +52,11 @@ reg [15:0] DATA_OUT; reg DATA_DIR; assign DATA=DATA_DIR ? 16'hz:DATA_OUT; -`define L1_CACHE_SIZE 4 // Don't change this! some parts of the code assume this +`define FIFO_SIZE_BYTES $rtoi($pow(2,`L1_CACHE_SIZE)) -`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*/ +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; @@ -65,7 +64,6 @@ reg [3:0] biu_state; always @(negedge reset) begin biu_state <= `BIU_HALT; end - always @(posedge reset) begin biu_state <= `BIU_RESET; end @@ -76,10 +74,8 @@ 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_latch ) begin /* verilator lint_off BLKSEQ */ @@ -145,33 +141,30 @@ always @(posedge clock) begin end end + /*************** INSTRUCTION FIFO READ ***************/ `BIU_READ: begin - /* verilator lint_off BLKSEQ */ 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]; + 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]; + 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]; + 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 */ biu_state <= `BIU_NEXT_ACTION; read<=1; end - /*************** 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 @@ -194,7 +187,6 @@ always @(posedge clock) begin write <= 0; biu_state <= `BIU_WRITE_RELEASE; end - `BIU_PUT_BYTE:begin `ifdef DEBUG_DATA_READ_WRITES $display("Writing 8bit %02x at %04x",DATA[7:0],DATA_ADDRESS); @@ -288,10 +280,9 @@ 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+1][5:3]},fifoIsize); Is1 Is1(INPUT_FIFO[FIFO_start][7:0],Isit1); @@ -310,16 +301,16 @@ always @( proc_state ) begin was_dec<=0; /* verilator lint_off BLKSEQ */ FIFO_start = FIFO_start + {1'b0,Isize}; - INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};; /* verilator lint_on BLKSEQ */ + INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};; VALID_INSTRUCTION <= 0; end else if ( SIMPLE_MICRO==1 && was_simple == 1) begin was_simple<=0; was_dec<=0; /* verilator lint_off BLKSEQ */ FIFO_start = FIFO_start + {1'b0,Isize}; - INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};; /* verilator lint_on BLKSEQ */ + INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {12'b0,Isize};; VALID_INSTRUCTION <= 0; end end @@ -336,54 +327,3 @@ always @( posedge jump_req ) begin end endmodule - -/* Pre-Decode the instruction size */ -/* IN: {CIR[15:8],CIR[5:3]} */ -/* OUT: number in bytes */ -module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT ); - always @( IN ) begin - casez(IN) - 11'b0000_010?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* ADD - Add Immediate word/byte to accumulator */ - 11'b1000_00??_101 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* SUB - Subtract immediate word/byte from register/memory */ - 11'b1000_00??_000 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* ADD - Add Immediate word/byte to register/memory */ - 11'b1000_00??_111 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* CMP - compare Immediate with register / memory */ - 11'b1011_????_??? : VERDICT <= 3'd2+{2'b0,IN[6:6]}; /* MOV - Move Immediate byte to register */ - 11'b1000_10??_??? : VERDICT <= 3'd2; /* MOV - Reg/Mem to/from register */ - 11'b0100_????_??? : VERDICT <= 3'd1; /* DEC - Decrement Register | INC - Increment Register */ - 11'b1111_111?_00? : VERDICT <= 3'd2; /* INC - Register/Memory | DEC - Register/Memory */ - 11'b1111_0100_??? : VERDICT <= 3'd1; /* HLT - Halt */ - 11'b0011_110?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* CMP - Compare Immediate with accumulator */ - 11'b0111_????_??? : VERDICT <= 3'd2; /* Conditional relative jumps ( JE/JZ, JS/JNS ... ) */ - 11'b1110_1011_??? : VERDICT <= 3'd2; /* JMP - Unconditional jump direct within segment (short) */ - 11'b1110_1000_??? : VERDICT <= 3'd3; /* CALL - Direct call within segment */ - 11'b1100_0011_??? : VERDICT <= 3'd1; /* RET - Return from call within segment */ - 11'b1010_101?_??? : VERDICT <= 3'd1; /* STOS - Write byte/word to [DI] and increment accordingly */ - 11'b0101_0???_??? : VERDICT <= 3'd1; /* PUSH - SP-=2; [SP]=REG */ - 11'b1111_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ - 11'b0101_1???_??? : VERDICT <= 3'd1; /* POP - REG=[SP]; SP+=2 */ - 11'b1111_1111_100 : VERDICT <= 3'd2; /* JMP - Unconditional indirect within segment jump */ - 11'b1100_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* MOV - Move immediate to register/memory */ - 11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */ - 11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */ - 11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */ - default:begin end - 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 1d8feaa..3e17d9c 100644 --- a/system/config.v +++ b/system/config.v @@ -29,9 +29,16 @@ * for the maximum instruction size worth of bytes */ `define EARLY_VALID_INSTRUCTION +/* Size is in powers of two with minimal 3. + * 3 : 8 Bytes + * 4 : 16 Bytes + * 5 : 32 Bytes + * . : ... */ +`define L1_CACHE_SIZE 4 // Don't change it! some parts of code still assume it to be 4 -/* Internal */ + +/********** Internal **********/ `ifdef EARLY_VALID_INSTRUCTION `define EARLY_VALID_INSTRUCTION_ 1 `else diff --git a/system/decoder.v b/system/decoder.v index 1a908c2..1511fe4 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -43,37 +43,64 @@ assign DATA=ucode_rom[ADDR]; endmodule -// verilator lint_off UNUSEDSIGNAL module decoder( - input wire [15:0] CIR,input wire [15:0] FLAGS, output wire [2:0] INSTRUCTION_INFO, output wire [`ERROR_BITS:0] DECODER_SIGNALS, output reg [`EXEC_STATE_BITS-1:0] next_state - ,output reg [2:0]IN_MOD, output reg [2:0]RM, output reg [15:0] PARAM1,output reg [15:0] PARAM2 - ,output reg [1:0]in_alu_sel1,output reg [1:0]in_alu_sel2,output reg [2:0]OUT_MOD - ,output wire [11:0]REGISTER_FILE_CONTROL - ,output reg [2:0]ALU_1OP - ,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 reg memio_address_select - ,output reg MEM_OR_IO + /* 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 + /* OUTPUT */ ,output wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] OUTPUT ); -// verilator lint_on UNUSEDSIGNAL + +reg [2:0]IN_MOD; +assign OUTPUT[2:0] = IN_MOD; + +reg [2:0]RM; +assign OUTPUT[5:3] = RM; + +reg memio_address_select; +assign OUTPUT[6:6] = memio_address_select; + +reg MEM_OR_IO; +assign OUTPUT[7:7] = MEM_OR_IO; + +reg [15:0] PARAM1; +assign OUTPUT[23:8] = PARAM1; + +reg [15:0] PARAM2; +assign OUTPUT[39:24] = PARAM2; + +reg [2:0]ALU_OP; +assign OUTPUT[42:40] = ALU_OP; + +reg [1:0]in_alu_sel1; +assign OUTPUT[44:43] = in_alu_sel1; + +reg [1:0]in_alu_sel2; +assign OUTPUT[46:45] = in_alu_sel2; + +reg [2:0]OUT_MOD; +assign OUTPUT[49:47] = OUT_MOD; reg [3:0]reg_read_port1_addr; -reg [3:0]reg_read_port2_addr; -reg [3:0]reg_write_addr; -assign REGISTER_FILE_CONTROL={reg_write_addr,reg_read_port1_addr,reg_read_port2_addr}; +assign OUTPUT[53:50] = reg_read_port1_addr; + +reg [3:0]reg_read_port2_addr; +assign OUTPUT[57:54] = reg_read_port2_addr; + +reg [3:0]reg_write_addr; +assign OUTPUT[61:58] = reg_write_addr; -/* For correct fetching of instructions and global options for the alu */ reg Wbit,Sbit,opcode_size; -assign INSTRUCTION_INFO={Wbit,Sbit,opcode_size}; +assign OUTPUT[64:62] = {Wbit,Sbit,opcode_size}; reg [`ERROR_BITS-1:0] ERROR; reg HALT; -assign DECODER_SIGNALS={ERROR,HALT}; +assign OUTPUT[`ERROR_BITS+65:65]={ERROR,HALT}; +reg [`EXEC_STATE_BITS-1:0] next_state; +assign OUTPUT[`EXEC_STATE_BITS+`ERROR_BITS+65:`ERROR_BITS+66] = next_state; - -// verilator lint_off UNUSEDSIGNAL +/* verilator lint_off UNUSEDSIGNAL */ wire [`UCODE_DATA_BITS-1:0] ucode_data; -// verilator lint_on UNUSEDSIGNAL +/* verilator lint_on UNUSEDSIGNAL */ microcode ucode(seq_addr_input,ucode_data); @@ -97,7 +124,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin 11'b0000_010?_??? : begin /* ADD - Add Immediate word/byte to accumulator */ /* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/ - opcode_size=0; //TODO: move the decoding done in BIU here and use theat size checker + opcode_size=0; Wbit=CIR[8:8]; IN_MOD=3'b011; in_alu_sel1=2'b00; @@ -106,7 +133,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin MEM_OR_IO=0; reg_read_port2_addr={Wbit,3'b000}; reg_write_addr={Wbit,3'b000}; - ALU_1OP=`ALU_OP_ADD; + ALU_OP=`ALU_OP_ADD; memio_address_select=0; if(Wbit) next_state=`EXEC_DE_LOAD_16_PARAM; @@ -148,8 +175,8 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin end endcase case(CIR[5:3]) - 3'b000: ALU_1OP=`ALU_OP_ADD; - 3'b101: ALU_1OP=`ALU_OP_SUB_REVERSE; + 3'b000: ALU_OP=`ALU_OP_ADD; + 3'b101: ALU_OP=`ALU_OP_SUB_REVERSE; default:begin /*Should be impossible*/ `invalid_instruction @@ -171,7 +198,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel1=2'b00; OUT_MOD=3'b100; MEM_OR_IO=0; - ALU_1OP=`ALU_OP_SUB; + ALU_OP=`ALU_OP_SUB; memio_address_select=0; if(IN_MOD==3'b011)begin /*compare register with param*/ @@ -199,7 +226,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin reg_write_addr={1'b0,CIR[10:8]}; PARAM1[7:0]=CIR[7:0]; PARAM2=0; - ALU_1OP=`ALU_OP_ADD; + ALU_OP=`ALU_OP_ADD; next_state=`EXEC_WRITE_ENTRY; `normal_instruction; memio_address_select=0; @@ -214,7 +241,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin OUT_MOD=3'b011; MEM_OR_IO=0; reg_write_addr={1'b1,CIR[10:8]}; - ALU_1OP=`ALU_OP_ADD; + ALU_OP=`ALU_OP_ADD; PARAM2=0; next_state=`EXEC_DE_LOAD_16_PARAM; `normal_instruction; @@ -260,7 +287,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin end reg_read_port2_addr={Wbit,CIR[5:3]}; end - ALU_1OP=`ALU_OP_ADD; + ALU_OP=`ALU_OP_ADD; `normal_instruction; memio_address_select=0; @@ -281,9 +308,9 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin reg_read_port1_addr={1'b1,CIR[10:8]}; reg_write_addr={1'b1,CIR[10:8]}; if(CIR[11:11]==0) - ALU_1OP=`ALU_OP_ADD; + ALU_OP=`ALU_OP_ADD; else - ALU_1OP=`ALU_OP_SUB; + ALU_OP=`ALU_OP_SUB; next_state=`EXEC_WRITE_ENTRY; `normal_instruction; memio_address_select=0; @@ -307,7 +334,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin reg_read_port2_addr={1'b0,RM}; reg_write_addr={1'b0,RM}; - ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD; + ALU_OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD; if ( IN_MOD == 3'b011 ) next_state=`EXEC_WRITE_ENTRY; else @@ -340,7 +367,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel2=2'b01; reg_read_port2_addr={Wbit,3'b000}; OUT_MOD=3'b100; - ALU_1OP=`ALU_OP_SUB; + ALU_OP=`ALU_OP_SUB; MEM_OR_IO=0; if(Wbit==1) next_state=`EXEC_DE_LOAD_16_PARAM; @@ -365,7 +392,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel1=2'b10; in_alu_sel2=2'b00; PARAM2={{8{CIR[7:7]}},CIR[7:0]}; - ALU_1OP=`ALU_OP_ADD_SIGNED_B; + ALU_OP=`ALU_OP_ADD_SIGNED_B; MEM_OR_IO=0; OUT_MOD=3'b101; case(CIR[11:9]) @@ -413,7 +440,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel1=2'b10; in_alu_sel2=2'b00; PARAM2={{8{CIR[7:7]}},CIR[7:0]}; - ALU_1OP=`ALU_OP_ADD_SIGNED_B; + ALU_OP=`ALU_OP_ADD_SIGNED_B; OUT_MOD=3'b101; MEM_OR_IO=0; next_state=`EXEC_WRITE_ENTRY; @@ -484,7 +511,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin next_state=`EXEC_DE_LOAD_8_PARAM; end in_alu_sel1=2'b00; /* PARAM1 */ - ALU_1OP=`ALU_OP_AND; + ALU_OP=`ALU_OP_AND; case(IN_MOD) 3'b011:begin in_alu_sel2=2'b01; @@ -527,7 +554,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu_sel2=2'b00; next_state=`EXEC_MEMIO_READ; end - ALU_1OP=`ALU_OP_ADD; + ALU_OP=`ALU_OP_ADD; OUT_MOD=3'b101; `normal_instruction; memio_address_select=0; @@ -623,14 +650,14 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin /*1:1 map essentially but I want to keep the spec for these bits separate * from the alu op select bits*/ case(ucode_data[22:20]) - 3'b000: ALU_1OP=`ALU_OP_ADD; - 3'b001: ALU_1OP=`ALU_OP_SUB; - 3'b010: ALU_1OP=`ALU_OP_AND; - 3'b011: ALU_1OP=`ALU_OP_OR; - 3'b100: ALU_1OP=`ALU_OP_XOR; - 3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B; - 3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE; - 3'b111: ALU_1OP=`ALU_OP_SHIFT_LEFT; + 3'b000: ALU_OP=`ALU_OP_ADD; + 3'b001: ALU_OP=`ALU_OP_SUB; + 3'b010: ALU_OP=`ALU_OP_AND; + 3'b011: ALU_OP=`ALU_OP_OR; + 3'b100: ALU_OP=`ALU_OP_XOR; + 3'b101: ALU_OP=`ALU_OP_ADD_SIGNED_B; + 3'b110: ALU_OP=`ALU_OP_SUB_REVERSE; + 3'b111: ALU_OP=`ALU_OP_SHIFT_LEFT; default: begin end endcase if(ucode_data[34:34]==0) /* Set reg read port 1 address */ @@ -649,3 +676,54 @@ end endmodule // verilator lint_on BLKSEQ + + +/* IN: {CIR[15:8],CIR[5:3]} */ +/* OUT: number in bytes */ +module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT ); + always @( IN ) begin + casez(IN) + 11'b0000_010?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* ADD - Add Immediate word/byte to accumulator */ + 11'b1000_00??_101 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* SUB - Subtract immediate word/byte from register/memory */ + 11'b1000_00??_000 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* ADD - Add Immediate word/byte to register/memory */ + 11'b1000_00??_111 : VERDICT <= 3'd3+{2'b0,(IN[4:3]==2'b01)}; /* CMP - compare Immediate with register / memory */ + 11'b1011_????_??? : VERDICT <= 3'd2+{2'b0,IN[6:6]}; /* MOV - Move Immediate byte to register */ + 11'b1000_10??_??? : VERDICT <= 3'd2; /* MOV - Reg/Mem to/from register */ + 11'b0100_????_??? : VERDICT <= 3'd1; /* DEC - Decrement Register | INC - Increment Register */ + 11'b1111_111?_00? : VERDICT <= 3'd2; /* INC - Register/Memory | DEC - Register/Memory */ + 11'b1111_0100_??? : VERDICT <= 3'd1; /* HLT - Halt */ + 11'b0011_110?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* CMP - Compare Immediate with accumulator */ + 11'b0111_????_??? : VERDICT <= 3'd2; /* Conditional relative jumps ( JE/JZ, JS/JNS ... ) */ + 11'b1110_1011_??? : VERDICT <= 3'd2; /* JMP - Unconditional jump direct within segment (short) */ + 11'b1110_1000_??? : VERDICT <= 3'd3; /* CALL - Direct call within segment */ + 11'b1100_0011_??? : VERDICT <= 3'd1; /* RET - Return from call within segment */ + 11'b1010_101?_??? : VERDICT <= 3'd1; /* STOS - Write byte/word to [DI] and increment accordingly */ + 11'b0101_0???_??? : VERDICT <= 3'd1; /* PUSH - SP-=2; [SP]=REG */ + 11'b1111_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */ + 11'b0101_1???_??? : VERDICT <= 3'd1; /* POP - REG=[SP]; SP+=2 */ + 11'b1111_1111_100 : VERDICT <= 3'd2; /* JMP - Unconditional indirect within segment jump */ + 11'b1100_011?_000 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* MOV - Move immediate to register/memory */ + 11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */ + 11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */ + 11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */ + default:begin end + 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/execute.v b/system/execute.v index a72c199..01189d6 100644 --- a/system/execute.v +++ b/system/execute.v @@ -1,3 +1,22 @@ +/* execute.v - Implements the instruction execution logic + + This file is part of the 9086 project. + + Copyright (c) 2023 Efthymios Kritikos + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + 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!!*/ @@ -13,12 +32,11 @@ module execute_unit ( assign _exec_state_ = exec_state; assign _ALU_O_ = ALU_O; -/*############ ALU / Execution units ########################################################## */ -// ALU 1 reg [`EXEC_STATE_BITS-1:0] exec_state; - reg [15:0] PARAM1,PARAM2; +/*############ ALU / Execution units ################################################## */ + mux4 #(.WIDTH(16)) MUX16_1A( /*0*/ PARAM1, /*1*/ reg_read_port1_data, @@ -41,28 +59,24 @@ wire [15:0] ALU_O; wire [7:0] ALU_FLAGS; ALU ALU1( - .A(ALU_A), - .B(ALU_B), - .OUT(ALU_O), - .op(ALU_OP), - .FLAGS(ALU_FLAGS), - .Wbit(Wbit) -); + /* INPUT 1 */ .A(ALU_A), + /* INPUT 2 */ .B(ALU_B), + /* OUTPUT */ .OUT(ALU_O), + /* OPERATION */ .op(ALU_OP), + /* FLAGS */ .FLAGS(ALU_FLAGS), + /* Wbit */ .Wbit(Wbit) + ); -//reg valid_input_; +/*############ Execute logic ########################################################## */ always @(posedge valid_input) begin exec_state <= init_state; - //valid_input_ <= 1; end always @(negedge set_initial_values) begin PARAM1 <= PARAM1_INIT; PARAM2 <= PARAM2_INIT; end -//always @(negedge valid_input) begin -// valid_input_ <= 0; -//end always @(negedge reset) begin exec_state <= `EXEC_HALT; @@ -76,7 +90,6 @@ end always @(posedge clock) begin case (exec_state) `EXEC_RESET: begin - //valid_input_ <= 0; biu_write_request <= 0; biu_read_request <= 0; biu_data_direction <= 0; @@ -87,7 +100,6 @@ always @(posedge clock) begin end `EXEC_DONE:begin reg_write_we <= 1; - //valid_input_ <= 0; biu_jump_req <= 0; use_exec_reg_addr <= 0; end diff --git a/system/processor.v b/system/processor.v index aa40d0c..4378ec8 100644 --- a/system/processor.v +++ b/system/processor.v @@ -23,194 +23,159 @@ `include "ucode_header.v" `include "error_header.v" -//HALT: active high -//IOMEM: 1=IO 0=MEM -//write: active low -//read: active low -//reset: active low - `define PROC_STATE_BITS 3 `define PROC_RESET 3'b000 `define PROC_DE_STATE_ENTRY 3'b001 `define PROC_WAIT 3'b010 `define PROC_HALT 3'b011 -module processor ( input clock, input reset, output [19:0] external_address_bus, inout [15:0] external_data_bus,output read, output write,output BHE,output IOMEM, output reg HALT,output [`ERROR_BITS-1:0] ERROR); +//HALT: active high +//IOMEM: 1=IO 0=MEM +//BHE: active low +//write: active low +//read: active low +//reset: active low + +module processor ( input clock, input reset, output [19:0] external_address_bus, inout [15:0] external_data_bus,output read, output write,output BHE,output IOMEM, output wire HALT,output [`ERROR_BITS-1:0] ERROR); /* If there is an error either from the decoder or execution unit set it to ERROR */ -assign ERROR=(DE_ERROR_sampled!=`ERR_NO_ERROR)?DE_ERROR_sampled:(EXEC_ERROR!=`ERR_NO_ERROR)?EXEC_ERROR:`ERR_NO_ERROR; +assign ERROR=(DE_ERROR!=`ERR_NO_ERROR)?DE_ERROR:(EXEC_ERROR!=`ERR_NO_ERROR)?EXEC_ERROR:`ERR_NO_ERROR; -/*** Global Definitions ***/ reg [`PROC_STATE_BITS-1:0] state; -/*############ Execution Unit ################################################## */ -reg [1:0] in_alu_sel1; -reg [1:0] in_alu_sel2; +/*############ Execution Unit ################################################### */ + +wire [1:0] in_alu_sel1, in_alu_sel2; +assign in_alu_sel1 = DE_OUTPUT_sampled[44:43]; +assign in_alu_sel2 = DE_OUTPUT_sampled[46:45]; wire [`EXEC_STATE_BITS-1:0] exec_state; -reg valid_exec_data; +reg valid_exec_data, set_initial_values; wire [`ERROR_BITS-1:0] EXEC_ERROR; wire use_exec_reg_addr; wire [3:0] EXEC_reg_read_port1_addr; -reg [2:0] IN_MOD,OUT_MOD; -reg [`EXEC_STATE_BITS-1:0] exec_state_init; -reg [`ALU_OP_BITS-1:0] ALU_OP; wire [15:0] ALU_O; wire [7:0]EXEC_FLAGS; -reg [15:0] PARAM1_INIT; -reg [15:0] PARAM2_INIT; -reg set_initial_values; + +wire [15:0] PARAM1_INIT, PARAM2_INIT; +assign PARAM1_INIT = DE_OUTPUT_sampled[23:8]; +assign PARAM2_INIT = DE_OUTPUT_sampled[39:24]; + +wire [2:0] IN_MOD,OUT_MOD; +assign IN_MOD=DE_OUTPUT_sampled[2:0]; +assign OUT_MOD=DE_OUTPUT_sampled[49:47]; + +wire [`ALU_OP_BITS-1:0] ALU_OP; +assign ALU_OP = DE_OUTPUT_sampled[42:40]; 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 /* PARAM */ ,PARAM1_INIT,PARAM2_INIT - /* STATE CONTROL */ ,exec_state, exec_state_init + /* STATE CONTROL */ ,exec_state, next_state /* ALU CONTROL */ ,in_alu_sel1, in_alu_sel2, ALU_OP, ALU_O /* REGISTER DATA */ ,reg_read_port1_data, reg_read_port2_data, EXEC_reg_read_port1_addr, use_exec_reg_addr, reg_write_we /* FLAFS */ ,EXEC_FLAGS /* BIU */ ,BIU_ADDRESS_INPUT, biu_write_request, biu_read_request, BIU_VALID_DATA, BIU_DATA, biu_data_direction, biu_jump_req - ); + ); /*############ Bus Interface Unit ############################################### */ -wire [31:0] INSTRUCTION; -wire biu_jump_req; -wire VALID_INSTRUCTION; -wire [15:0] INSTRUCTION_LOCATION; -wire [15:0] BIU_ADDRESS_INPUT; +wire [15:0] INSTRUCTION_LOCATION, BIU_ADDRESS_INPUT; wire [15:0] BIU_DATA; -wire biu_write_request; -wire biu_data_direction; -wire biu_read_request; -wire BIU_VALID_DATA; +wire [31:0] INSTRUCTION; +wire biu_write_request, biu_read_request, BIU_VALID_DATA; +wire biu_jump_req, biu_data_direction,VALID_INSTRUCTION; BIU BIU( - clock,reset,external_address_bus,external_data_bus,read,write,BHE,IOMEM, - 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 -); + /* Outside world */ clock,reset,external_address_bus + /* */ ,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 + ); assign BIU_DATA= biu_data_direction ? 16'hz : (memio_address_select ? reg_read_port1_data : ALU_O); /*############ Decoder ########################################################## */ -reg Wbit, Sbit, opcode_size; -wire DE_Wbit, DE_Sbit, DE_opcode_size; -wire [`EXEC_STATE_BITS-1:0] next_state; -reg [2:0]RM; -wire [15:0]DE_PARAM1;// Input param1 form decoder to alu -wire [15:0]DE_PARAM2; -wire [2:0]DE_IN_MOD; -wire [2:0]DE_RM; -wire [2:0]DE_OUT_MOD; -wire [`ERROR_BITS-1:0] DE_ERROR; -wire DE_HALT; -wire [3:0]DE_reg_read_port1_addr,DE_reg_write_addr,DE_reg_read_port2_addr; -wire [11:0]DE_REGISTER_CONTROL; -wire [2:0]INSTRUCTION_INFO; -wire [`ERROR_BITS:0]DECODER_SIGNALS; + wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry; - -reg SIMPLE_MICRO; /* output simple decodings (=0) or microcode data (=1) */ -//TODO : remove completely? -reg memio_address_select; -wire DE_memio_address_select; -wire DE_MEM_OR_IO; -reg MEM_OR_IO; -wire [1:0] DE_in_alu_sel1; -wire [1:0] DE_in_alu_sel2; -reg [`ALU_OP_BITS-1:0] DE_ALU_OP; -decoder decoder( - .CIR(INSTRUCTION[31:16]), - .FLAGS(FLAGS), - .INSTRUCTION_INFO(INSTRUCTION_INFO), - .DECODER_SIGNALS(DECODER_SIGNALS), - .next_state(next_state), - .IN_MOD(DE_IN_MOD), - .RM(DE_RM), - .PARAM1(DE_PARAM1), - .PARAM2(DE_PARAM2), - .in_alu_sel1(DE_in_alu_sel1), - .in_alu_sel2(DE_in_alu_sel2), - .OUT_MOD(DE_OUT_MOD), - .REGISTER_FILE_CONTROL(DE_REGISTER_CONTROL), - .ALU_1OP(DE_ALU_OP), - .seq_addr_entry(ucode_seq_addr_entry), - .SIMPLE_MICRO(SIMPLE_MICRO), - .seq_addr_input(ucode_seq_addr), - .memio_address_select(DE_memio_address_select), - .MEM_OR_IO(DE_MEM_OR_IO) -); - -assign DE_Wbit=INSTRUCTION_INFO[2:2]; -assign DE_Sbit=INSTRUCTION_INFO[1:1]; -assign DE_opcode_size=INSTRUCTION_INFO[0:0]; - -assign DE_reg_write_addr=DE_REGISTER_CONTROL[11:8]; -assign DE_reg_read_port1_addr=DE_REGISTER_CONTROL[7:4]; -assign DE_reg_read_port2_addr=DE_REGISTER_CONTROL[3:0]; - -assign DE_HALT=DECODER_SIGNALS[0:0]; -assign DE_ERROR=DECODER_SIGNALS[`ERROR_BITS:1]; -reg [`ERROR_BITS-1:0] DE_ERROR_sampled; - reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr; +reg SIMPLE_MICRO; /* output simple decodings (=0) or microcode data (=1) */ -/*############ REGISTERS ########################################################## */ +wire [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT; +reg [`EXEC_STATE_BITS+`ERROR_BITS+65:0] DE_OUTPUT_sampled; +decoder decoder( + /* INPUTS */ INSTRUCTION[31:16],FLAGS, + /* MICROCODE */ ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr, + /* OUTPUT */ DE_OUTPUT + ); + +wire [2:0] RM; +assign RM = DE_OUTPUT_sampled[5:3]; + +wire memio_address_select; +assign memio_address_select=DE_OUTPUT_sampled[6:6]; + +wire [3:0] DE_reg_read_port1_addr,DE_reg_read_port2_addr; +assign DE_reg_read_port1_addr=DE_OUTPUT_sampled[53:50]; +assign DE_reg_read_port2_addr=DE_OUTPUT_sampled[57:54]; + +wire [3:0] reg_write_addr; +assign reg_write_addr=DE_OUTPUT_sampled[61:58]; + +wire MEM_OR_IO; +assign MEM_OR_IO = DE_OUTPUT_sampled[7:7]; + +wire Wbit, Sbit, opcode_size; +assign opcode_size=DE_OUTPUT_sampled[62:62]; +assign Sbit=DE_OUTPUT_sampled[63:63]; +assign Wbit=DE_OUTPUT_sampled[64:64]; + +wire [`ERROR_BITS-1:0] DE_ERROR; +assign HALT = DE_OUTPUT_sampled[65:65]; +assign DE_ERROR = DE_OUTPUT_sampled[`ERROR_BITS+65:66]; + +wire [`EXEC_STATE_BITS-1:0] next_state; +assign next_state=DE_OUTPUT_sampled[`EXEC_STATE_BITS+`ERROR_BITS+65:`ERROR_BITS+66]; + +/*############ Registers ######################################################## */ -// verilator lint_off UNDRIVEN reg [15:0] FLAGS; -// verilator lint_on UNDRIVEN - -//Architectural Register file -reg [3:0] reg_write_addr; -wire [15:0] reg_write_data; -wire reg_write_we; -wire [3:0] reg_read_port1_addr; -reg [15:0] reg_read_port1_data; -reg [3:0] reg_read_port2_addr; -reg [15:0] reg_read_port2_data; -reg [1:0] reg_write_in_sel; - -mux4 #(.WIDTH(16)) REG_FILE_WRITE_IN_MUX( - ALU_O, - 16'hz, - 16'hz, - 16'hz, - reg_write_in_sel, - reg_write_data); - -register_file register_file( - .write_port1_addr(reg_write_addr), - .write_port1_data(reg_write_data), - .write_port1_we(reg_write_we), - .read_port1_addr(reg_read_port1_addr), - .read_port1_data(reg_read_port1_data), - .read_port2_addr(reg_read_port2_addr), - .read_port2_data(reg_read_port2_data) -); - -assign reg_read_port1_addr = use_exec_reg_addr ? EXEC_reg_read_port1_addr : reg_read_port1_addr_latched; - reg [15:0] ProgCount; -/*############ Processor state machine ########################################################## */ -reg [3:0] reg_read_port1_addr_latched; +wire [3:0] reg_read_port1_addr; +assign reg_read_port1_addr = use_exec_reg_addr ? EXEC_reg_read_port1_addr : DE_reg_read_port1_addr; + +wire [15:0] reg_read_port1_data, reg_read_port2_data; + +wire reg_write_we; + +register_file register_file( + /* WRITE */ .write_port1_addr(reg_write_addr), + /* */ .write_port1_data(ALU_O), + /* */ .write_port1_we(reg_write_we), + /* READ 1 */ .read_port1_addr(reg_read_port1_addr), + /* */ .read_port1_data(reg_read_port1_data), + /* READ 2 */ .read_port2_addr(DE_reg_read_port2_addr), + /* */ .read_port2_data(reg_read_port2_data) + ); + +/*############ Processor State Machine ########################################## */ /*** RESET LOGIC ***/ -/* verilator lint_off MULTIDRIVEN */ + always @(negedge reset) begin state <= `PROC_HALT; //TODO: race condition ?? end always @(posedge reset) begin state <= `PROC_RESET; end -/* verilator lint_on MULTIDRIVEN */ /*** Processor stages ***/ @@ -219,49 +184,28 @@ InstrSize InstrSize({INSTRUCTION[31:24],INSTRUCTION[21:19]},instr_end); reg [23:0] INSTRUCTION_BUFFER; - always @(posedge clock) begin case(state) `PROC_RESET:begin ucode_seq_addr <= `UCODE_NO_INSTRUCTION; - HALT <= 0; + DE_OUTPUT_sampled <= 0; SIMPLE_MICRO <= 0; state <= `PROC_DE_STATE_ENTRY; - reg_write_in_sel <= 2'b00; //only got wirtten in IF end `PROC_DE_STATE_ENTRY:begin if(VALID_INSTRUCTION==1) begin + + DE_OUTPUT_sampled <= DE_OUTPUT; + if(SIMPLE_MICRO==0)begin - /* We cannot set these directly within - * microcode so don't overwrite useful values - * each tie the next microcode is executed. - * Note this still allows to set initial values - * at the start of the microcode */ - PARAM1_INIT <= DE_PARAM1; - PARAM2_INIT <= DE_PARAM2; + 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]; - set_initial_values<=0; end - DE_ERROR_sampled <= DE_ERROR; - IN_MOD <= DE_IN_MOD; - OUT_MOD <= DE_OUT_MOD; - RM <= DE_RM; - HALT <= DE_HALT; - Wbit <= DE_Wbit; - Sbit <= DE_Sbit; - opcode_size <= DE_opcode_size; - memio_address_select<=DE_memio_address_select; - reg_read_port1_addr_latched <= DE_reg_read_port1_addr; - reg_read_port2_addr <= DE_reg_read_port2_addr; - reg_write_addr <= DE_reg_write_addr; - MEM_OR_IO <= DE_MEM_OR_IO; - in_alu_sel1 <= DE_in_alu_sel1; - in_alu_sel2 <= DE_in_alu_sel2; - ALU_OP <= DE_ALU_OP; 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; @@ -269,7 +213,6 @@ always @(posedge clock) begin /*keep state the same and rerun decode this time with all the data from the microcode rom*/ end else begin valid_exec_data <= 1; - exec_state_init <= next_state; state <= `PROC_WAIT; end end @@ -277,10 +220,10 @@ always @(posedge clock) begin `PROC_WAIT:begin set_initial_values<=1; if( exec_state == `EXEC_DONE ) begin - FLAGS[7:0] <= EXEC_FLAGS; //don't set all of them all the time! + FLAGS <= {8'b0,EXEC_FLAGS}; //TODO: don't set all of them all the time! valid_exec_data<=0; state <= `PROC_DE_STATE_ENTRY; - if(SIMPLE_MICRO == 1 ) begin + if( SIMPLE_MICRO == 1 ) begin ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin /*Finished microcode*/ @@ -296,5 +239,4 @@ always @(posedge clock) begin endcase end - endmodule