diff --git a/system/alu.v b/system/alu.v index 4abe1b4..4ae3a79 100644 --- a/system/alu.v +++ b/system/alu.v @@ -26,7 +26,7 @@ wire signed [7:0]SIGNED_8B; assign SIGNED_B=B; assign SIGNED_8B=B[7:0]; -assign FLAGS={(Wbit==1)?OUT[15:15]:OUT[7:7],(Wbit==1) ? (OUT[15:0]=='h0000) : (OUT[7:0]=='h00),5'b00000,C_FLAG}; +assign FLAGS={(Wbit==1)?OUT[15:15]:OUT[7:7],(Wbit==1) ? (OUT[15:0]=='h0000) : (OUT[7:0]=='h00),5'b0,C_FLAG}; always @ ( * ) begin if(Wbit==1)begin @@ -35,9 +35,9 @@ always @ ( * ) begin `ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT}=A+SIGNED_B; `ALU_OP_SUB: {C_FLAG,OUT}=A-B; `ALU_OP_SUB_REVERSE: {C_FLAG,OUT}=B-A; - `ALU_OP_AND: OUT=A&B; - `ALU_OP_OR: OUT=A|B; - `ALU_OP_XOR: OUT=A^B; + `ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end + `ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end + `ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end default:begin OUT=0; C_FLAG=0; @@ -49,9 +49,9 @@ always @ ( * ) begin `ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT[7:0]}=A[7:0]+SIGNED_8B; `ALU_OP_SUB: {C_FLAG,OUT[7:0]}=A[7:0]-B[7:0]; `ALU_OP_SUB_REVERSE: {C_FLAG,OUT[7:0]}=B[7:0]-A[7:0]; - `ALU_OP_AND: OUT=A&B; - `ALU_OP_OR: OUT=A|B; - `ALU_OP_XOR: OUT=A^B; + `ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end + `ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end + `ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end default:begin OUT=0; C_FLAG=0; diff --git a/system/decoder.v b/system/decoder.v index 2df346d..6ec3bf6 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -29,19 +29,20 @@ module microcode( initial begin string ucode_path; if($value$plusargs("MICROCODE=%s",ucode_path))begin - $readmemb(ucode_path,ucode,0,`UCODE_SIZE-1); + $readmemb(ucode_path,ucode_rom,0,`UCODE_SIZE-1); end else begin $display("Please supply microcode rom file as a runtime vvp argument +MICROCODE="); $finish; end end -reg [`UCODE_DATA_BITS-1:0] ucode [ 0:`UCODE_SIZE-1 ]; +reg [`UCODE_DATA_BITS-1:0] ucode_rom [ 0:`UCODE_SIZE-1 ]; -assign DATA=ucode[ADDR]; +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 [1:0]DECODER_SIGNALS,output reg [`PROC_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 @@ -51,6 +52,7 @@ module decoder( ,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 [2:0]instruction_size ); +// verilator lint_on UNUSEDSIGNAL reg [3:0]reg_read_port1_addr; reg [3:0]reg_read_port2_addr; @@ -66,23 +68,31 @@ assign DECODER_SIGNALS={ERROR,HALT}; +// verilator lint_off UNUSEDSIGNAL wire [`UCODE_DATA_BITS-1:0] ucode_data; -reg [`UCODE_ADDR_BITS-1:0] UCODE_ADDR; +// verilator lint_on UNUSEDSIGNAL + microcode ucode(seq_addr_input,ucode_data); /* 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 */ -`define invalid_instruction next_state=`PROC_IF_STATE_ENTRY;ERROR=1;IN_MOD=2'b11; +`define invalid_instruction next_state=`PROC_IF_STATE_ENTRY;ERROR<=1;IN_MOD=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION; + //TODO: A possible optimisation for instruction with 8bit parameter and //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<=0;HALT<=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 +// would be identical +// verilator lint_off BLKSEQ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin if (SIMPLE_MICRO==0)begin - ERROR=0;HALT=0;seq_addr_entry=`UCODE_NO_INSTRUCTION; - casex({CIR[15:8],CIR[5:3]}) - 11'b0000_010x_xxx : begin + casez({CIR[15:8],CIR[5:3]}) + 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; @@ -92,7 +102,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end else begin instruction_size=2; end - IN_MOD=2'b11; + IN_MOD=3'b011; in_alu1_sel1=2'b00; in_alu1_sel2=2'b01; OUT_MOD=3'b011; @@ -103,9 +113,10 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin next_state=`PROC_DE_LOAD_16_PARAM; else next_state=`PROC_DE_LOAD_8_PARAM; + `normal_instruction; end - 11'b1000_00xx_101, /* SUB */ - 11'b1000_00xx_000 : /* ADD */ begin + 11'b1000_00??_101, /* SUB */ + 11'b1000_00??_000 : /* ADD */ begin /* ADD - Add Immediate word/byte to register/memory */ /* 1 0 0 0 0 0 S W | MOD 0 0 0 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */ /* SUB - Subtract immediate word/byte from register/memory */ @@ -113,17 +124,17 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin opcode_size=1; Wbit=CIR[8:8]; Sbit=CIR[9:9]; - IN_MOD=CIR[7:6]; + IN_MOD={1'b0,CIR[7:6]}; RM=CIR[2:0]; in_alu1_sel1=2'b00; - if(IN_MOD==2'b11)begin + if(IN_MOD==3'b011)begin in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; reg_write_addr={Wbit,RM}; end else begin in_alu1_sel2=2'b00; end - OUT_MOD={1'b0,IN_MOD}; + OUT_MOD=IN_MOD; case({Sbit,Wbit}) 2'b00,2'b11:begin next_state=`PROC_DE_LOAD_8_PARAM; @@ -145,14 +156,15 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin `invalid_instruction end endcase + `normal_instruction; end - 11'b1000_00xx_111 : begin + 11'b1000_00??_111 : begin /* CMP - compare Immediate with register / memory */ /* 1 0 0 0 0 0 S W | MOD 1 1 1 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */ opcode_size=1; Wbit=CIR[8:8]; Sbit=CIR[9:9]; - IN_MOD=CIR[7:6]; + IN_MOD={1'b0,CIR[7:6]}; RM=CIR[2:0]; case({Sbit,Wbit}) 2'b00,2'b11:begin @@ -168,7 +180,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu1_sel1=2'b00; OUT_MOD=3'b100; ALU_1OP=`ALU_OP_SUB; - if(IN_MOD==2'b11)begin + if(IN_MOD==3'b011)begin /*compare register with param*/ in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; @@ -179,14 +191,15 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu1_sel2=2'b00; next_state=`PROC_DE_LOAD_16_PARAM; /*will the call MEMIO_READ*/ end + `normal_instruction; end - 11'b1011_0xxx_xxx : begin + 11'b1011_0???_??? : begin /* MOV - Move Immediate byte to register */ /* 1 0 1 1 W REG | DATA | DATA if W |*/ Wbit=CIR[11:11]; /* IS 0 */ instruction_size=2; opcode_size=0; - IN_MOD=2'b11; + IN_MOD=3'b011; in_alu1_sel1=2'b00; in_alu1_sel2=2'b00; OUT_MOD=3'b011; @@ -195,13 +208,14 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin PARAM2=0; ALU_1OP=`ALU_OP_ADD; next_state=`PROC_EX_STATE_ENTRY; + `normal_instruction; end - 11'b1011_1xxx_xxx : begin + 11'b1011_1???_??? : begin /*MOV - Move Immediate word to register*/ Wbit=CIR[11:11]; /*IS 1 */ instruction_size=3; opcode_size=0; - IN_MOD=2'b11; + IN_MOD=3'b011; in_alu1_sel1=2'b00; in_alu1_sel2=2'b00; OUT_MOD=3'b011; @@ -209,9 +223,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin ALU_1OP=`ALU_OP_ADD; PARAM2=0; next_state=`PROC_DE_LOAD_16_PARAM; + `normal_instruction; end - - 11'b1000_10xx_xxx : begin + 11'b1000_10??_??? : begin /* MOV - Reg/Mem to/from register */ /* 1 0 0 0 1 0 D W | MOD REG RM | < DISP LO > | < DISP HI > |*/ opcode_size=1; @@ -223,7 +237,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin if(CIR[9:9] == 1)begin /* Mem/Reg to reg */ IN_MOD={1'b0,CIR[7:6]}; - if(IN_MOD==2'b11)begin + if(IN_MOD==3'b011)begin /*Reg to Reg*/ in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; @@ -239,7 +253,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* Reg to Mem/Reg */ IN_MOD=3'b011; OUT_MOD={1'b0,CIR[7:6]}; - if(IN_MOD==2'b11)begin + if(IN_MOD==3'b011)begin /*Reg to Reg*/ in_alu1_sel2=2'b01; reg_write_addr={Wbit,RM}; @@ -251,10 +265,11 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end reg_read_port2_addr={Wbit,CIR[5:3]}; end - ALU_1OP=`ALU_OP_ADD; + + `normal_instruction; end - 11'b0100_xxxx_xxx:begin//DEC + 11'b0100_????_???:begin//DEC /* DEC - Decrement Register */ /* | 0 1 0 0 1 REG | */ /* INC - Increment Register */ @@ -265,7 +280,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu1_sel1=2'b01; in_alu1_sel2=2'b00; OUT_MOD=3'b011; - IN_MOD=2'b11; + IN_MOD=3'b011; PARAM2=1; reg_read_port1_addr={1'b1,CIR[10:8]}; reg_write_addr={1'b1,CIR[10:8]}; @@ -274,8 +289,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin else ALU_1OP=`ALU_OP_SUB; next_state=`PROC_EX_STATE_ENTRY; + `normal_instruction; end - 11'b1111_111x_00x : begin + 11'b1111_111?_00? : begin /* INC - Register/Memory */ /* 1 1 1 1 1 1 1 W | MOD 0 0 0 R/M | < DISP LO> | < DISP HI> */ /* DEC - Register/Memory */ @@ -283,33 +299,37 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin instruction_size=2; opcode_size=1; Wbit=CIR[8:8]; - IN_MOD=CIR[7:6]; + IN_MOD={1'b0,CIR[7:6]}; RM=CIR[2:0]; - in_alu1_sel2=(IN_MOD==2'b11)? 2'b01 : 2'b00; + in_alu1_sel2=(IN_MOD==3'b011)? 2'b01 : 2'b00; in_alu1_sel1=2'b00;/* number 1 */ PARAM1=1; - OUT_MOD={1'b0,IN_MOD}; + OUT_MOD=IN_MOD; - /*in case IN_MOD=11 */ + /*in case IN_MOD=011 */ 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; - if ( IN_MOD == 2'b11 ) + if ( IN_MOD == 3'b011 ) next_state=`PROC_EX_STATE_ENTRY; else next_state=`PROC_MEMIO_READ; + `normal_instruction; end - 11'b1111_0100_xxx : begin + 11'b1111_0100_??? : begin /* HLT - Halt */ /* 1 1 1 1 0 1 0 0 | */ instruction_size=1; opcode_size=0; - IN_MOD=2'b11; - HALT=1; + IN_MOD=3'b011; + HALT<=1; + ERROR<=0; + seq_addr_entry<=`UCODE_NO_INSTRUCTION; next_state=`PROC_HALT_STATE; + end - 11'b0011_110x_xxx : begin + 11'b0011_110?_??? : begin /* CMP - Compare Immediate with accumulator */ /* 0 0 1 1 1 1 0 W | DATA | DATA if W |*/ /* */ @@ -322,7 +342,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end else begin instruction_size=2; end - IN_MOD=2'b11; + IN_MOD=3'b011; in_alu1_sel1=2'b00; in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,3'b000}; @@ -334,8 +354,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin PARAM1[7:0]=CIR[7:0]; next_state=`PROC_EX_STATE_ENTRY; end + `normal_instruction; end - 11'b0111_xxxx_xxx:begin + 11'b0111_????_???:begin /* Conditional relative jumps */ /* JE/JZ - Jump on Zero */ /* 0 1 1 1 0 1 0 0 | IP-INC8 |*/ @@ -386,8 +407,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin `invalid_instruction; /*We don't support that condition*/ end endcase + `normal_instruction; end - 11'b1110_1011_xxx:begin + 11'b1110_1011_???:begin /* JMP - Unconditional jump direct within segment (short) */ /* | 1 1 1 0 1 0 1 1 | IP-INC-LO | */ instruction_size=2; @@ -399,8 +421,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin ALU_1OP=`ALU_OP_ADD_SIGNED_B; OUT_MOD=3'b101; next_state=`PROC_EX_STATE_ENTRY; + `normal_instruction; end - 11'b1100_1101_xxx:begin + 11'b1100_1101_???:begin /* INT - execute interrupt handler */ /* 1 1 0 0 1 1 0 1 | DATA |*/ instruction_size=2; @@ -410,8 +433,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin $write("%s" ,register_file.registers[2][7:0]); /*TODO:Could trigger erroneously while CIR is not final*/ end next_state=`PROC_IF_STATE_ENTRY; + `normal_instruction; end - 11'b1110_1000_xxx:begin + 11'b1110_1000_???:begin /* CALL - Direct call within segment */ /* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/ @@ -421,9 +445,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Wbit=1; Sbit=1; PARAM2=2; //subtract from sp - seq_addr_entry=`UCODE_CALL_ENTRY; + seq_addr_entry<=`UCODE_CALL_ENTRY; end - 11'b1100_0011_xxx:begin + 11'b1100_0011_???:begin /* RET - Return from call within segment */ /* | 1 1 0 0 0 0 1 1 | */ @@ -433,20 +457,20 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Wbit=1; Sbit=0; PARAM1=2; - seq_addr_entry=`UCODE_RET_ENTRY; + seq_addr_entry<=`UCODE_RET_ENTRY; end - 11'b1010_101x_xxx:begin + 11'b1010_101?_???:begin /* STOS - Write byte/word to [DI] and increment accordingly */ /* | 1 0 1 0 1 0 1 W | */ opcode_size=0; instruction_size=1; Wbit=CIR[8:8]; Sbit=0; - RM=101; - seq_addr_entry=`UCODE_STOS_ENTRY; + RM=3'b101; + seq_addr_entry<=`UCODE_STOS_ENTRY; PARAM2=(Wbit==1)?2:1; end - 11'b0101_0xxx_xxx:begin + 11'b0101_0???_???:begin /* PUSH - SP-=2; [SP]=REG */ /* | 0 1 0 1 0 REG | */ opcode_size=0; @@ -455,9 +479,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Sbit=0; PARAM2=2; reg_read_port2_addr={1'b1,CIR[10:8]}; - seq_addr_entry=`UCODE_PUSH_ENTRY; + seq_addr_entry<=`UCODE_PUSH_ENTRY; end - 11'b1111_011x_000:begin + 11'b1111_011?_000:begin /* TEST - Bitwise AND affecting only flags */ /* 1 1 1 1 0 1 1 W | MOD 0 0 0 R/M | < DISP-LO > | < DISP-HI > | DATA | DATA if W */ opcode_size=1; @@ -474,7 +498,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin in_alu1_sel1=2'b00; /* PARAM1 */ ALU_1OP=`ALU_OP_AND; case(IN_MOD) - 2'b11:begin + 3'b011:begin in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; end @@ -483,8 +507,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end endcase OUT_MOD=3'b100;/*NULL*/ + `normal_instruction; end - 11'b0101_1xxx_xxx:begin + 11'b0101_1???_???:begin /* POP - REG=[SP]; SP+=2 */ /* | 0 1 0 1 1 REG | */ opcode_size=0; @@ -493,7 +518,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Sbit=0; PARAM1=2; reg_write_addr={1'b1,CIR[10:8]}; - seq_addr_entry=`UCODE_POP_ENTRY; + seq_addr_entry<=`UCODE_POP_ENTRY; end 11'b1111_1111_100:begin /* JMP - Unconditional indirect within segment jump */ @@ -504,7 +529,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin IN_MOD={1'b0,CIR[7:6]}; RM=CIR[2:0]; in_alu1_sel1=2'b11; - if (IN_MOD==2'b11)begin + if (IN_MOD==3'b011)begin in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; next_state=`PROC_EX_STATE_ENTRY; @@ -514,8 +539,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end ALU_1OP=`ALU_OP_ADD; OUT_MOD=3'b101; + `normal_instruction; end - 11'b1100_011x_000:begin + 11'b1100_011?_000:begin /* MOV - Move immediate to register/memory */ /* 1 1 0 0 0 1 1 W | MOD 0 0 0 R/M | < DISP-LO > | < DISP-HI > | DATA | DATA if W */ Wbit=CIR[8:8]; @@ -533,7 +559,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin OUT_MOD={1'b0,CIR[7:6]}; IN_MOD=3'b011; RM=CIR[2:0]; - + `normal_instruction; end default:begin `invalid_instruction @@ -543,7 +569,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /*Microcode output*/ //Sbit, Wbit, opcode_size and the others are still latched //from when we ordered the switch to microcode - seq_addr_entry=ucode_data[5:0]; + seq_addr_entry <= ucode_data[`UCODE_ADDR_BITS-1:0]; case(ucode_data[7:6]) 2'b00: next_state=`PROC_EX_STATE_ENTRY; 2'b01: next_state=`PROC_DE_LOAD_16_PARAM; @@ -565,6 +591,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 3'b100: ALU_1OP=`ALU_OP_XOR; 3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B; 3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE; + default: begin end endcase if(ucode_data[33:33]==0) reg_read_port1_addr=ucode_data[25:22]; @@ -575,5 +602,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Wbit=ucode_data[36:36]; end end +`undef invalid_instruction endmodule +// verilator lint_on BLKSEQ diff --git a/system/proc_state_def.v b/system/proc_state_def.v index ffda0ed..161ba66 100644 --- a/system/proc_state_def.v +++ b/system/proc_state_def.v @@ -60,3 +60,5 @@ `define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2 6'b110010 `define PROC_NEXT_MICROCODE 6'b111000 + +`define PROC_RESET 6'b111100 diff --git a/system/processor.v b/system/processor.v index 054a4fe..9f158a5 100644 --- a/system/processor.v +++ b/system/processor.v @@ -98,9 +98,9 @@ reg [15:0] CIR; reg [15:0] PARAM1; reg [15:0] PARAM2; -reg [15:0]FLAGS; - -reg [15:0] BYTE_WRITE_TEMP_REG;//we read 16bits here if we want to change just 8 and leave the rest +// verilator lint_off UNDRIVEN +reg [15:0] FLAGS; +// verilator lint_on UNDRIVEN //Architectural Register file reg [3:0] reg_write_addr; @@ -129,10 +129,13 @@ register_file register_file( ); reg [15:0] ProgCount; -wire ProgCount_next_opcode; -wire ProgCount_arg; -assign ProgCount_next_opcode=ProgCount+instruction_size; -assign ProgCount_arg=ProgCount+opcode_size+1; + +// verilator lint_off UNUSEDSIGNAL +wire [15:0] ProgCount_next_opcode; +wire [15:0] ProgCount_arg; +assign ProgCount_next_opcode=ProgCount+{13'b0,instruction_size}; +assign ProgCount_arg=ProgCount+{15'b0,opcode_size}+16'd1; +// verilator lint_on UNUSEDSIGNAL /*############ ALU / Execution units ########################################################## */ // ALU 1 @@ -146,7 +149,7 @@ mux4 #(.WIDTH(16)) MUX16_1A( /*0*/ PARAM1, /*1*/ reg_read_port1_data, /*2*/ ProgCount[15:0], -/*3*/ 16'b0000000000000000, /*0 Constant*/ +/*3*/ 16'd0, /*0 Constant*/ in_alu1_sel1, ALU_1A); @@ -154,7 +157,7 @@ mux4 #(.WIDTH(16)) MUX16_1B( /*0*/ PARAM2, /*1*/ reg_read_port2_data, /*2*/ ProgCount[15:0], -/*3*/ 16'b0000000000000000, /*0 Constant*/ +/*3*/ 16'd0, /*0 Constant*/ in_alu1_sel2, ALU_1B); @@ -175,29 +178,31 @@ ALU ALU1( /*############ Processor state machine ########################################################## */ /*** RESET LOGIC ***/ +/* verilator lint_off MULTIDRIVEN */ always @(negedge reset) begin - if (reset==0) begin - @(posedge clock); - state=`PROC_HALT_STATE; - ucode_seq_addr=`UCODE_NO_INSTRUCTION; - ProgCount=0;//TODO: Reset Vector - HALT=0; - reg_write_we=1; - IOMEM=0; - @(posedge reset) - @(negedge clock); - state=`PROC_IF_STATE_ENTRY; - ERROR=0; - SIMPLE_MICRO=0; - instruction_size_init=1; - end + state <= `PROC_HALT_STATE; //TODO: race condition ?? end +always @(posedge reset) begin + state <= `PROC_RESET; +end +/* verilator lint_on MULTIDRIVEN */ /*** Processor stages ***/ -`define invalid_instruction state=`PROC_IF_STATE_ENTRY;ERROR=1; +`define invalid_instruction state <= `PROC_IF_STATE_ENTRY;ERROR <= 1; always @(posedge clock) begin case(state) + `PROC_RESET:begin + ucode_seq_addr <= `UCODE_NO_INSTRUCTION; + ProgCount <= 0;//TODO: Reset Vector + HALT <= 0; + ERROR <= 0; + IOMEM <= 0; + SIMPLE_MICRO <= 0; + reg_write_we <= 1; + instruction_size_init <= 1; + state <= `PROC_IF_STATE_ENTRY; + end `PROC_HALT_STATE:begin end `PROC_IF_STATE_ENTRY:begin @@ -213,13 +218,13 @@ always @(posedge clock) begin $display("Fetched instruction at %0x",ProgCount - 0); end `endif - BHE = 0; - external_address_bus = ProgCount; - read = 0; - write = 1; - reg_write_we=1; - state=`PROC_IF_WRITE_CIR; - reg_write_in_sel=2'b00; + BHE <= 0; + external_address_bus <= {4'b0,ProgCount}; + read <= 0; + write <= 1; + reg_write_we <= 1; + state <= `PROC_IF_WRITE_CIR; + reg_write_in_sel <= 2'b00; end `PROC_IF_WRITE_CIR:begin /*I built the entire decode stage with CIR @@ -227,40 +232,40 @@ always @(posedge clock) begin if(instruction_size==1)begin /*Half on CIR half on this address */ - state=`PROC_DE_STATE_ENTRY; + state <= `PROC_DE_STATE_ENTRY; if(ProgCount[0:0]==1)begin - CIR = {CIR[7:0],external_data_bus[15:8]}; + CIR <= {CIR[7:0],external_data_bus[15:8]}; end else begin - CIR = {CIR[7:0],external_data_bus[7:0]}; + CIR <= {CIR[7:0],external_data_bus[7:0]}; end - ProgCount=ProgCount+1; + ProgCount <= ProgCount+1; end else begin if(ProgCount[0:0]==1)begin /* Half on this address half on the next*/ - ProgCount=ProgCount+1; + ProgCount <= ProgCount+1; CIR[15:8] <= external_data_bus[15:8]; - state=`PROC_IF_STATE_EXTRA_FETCH_SET; + state <= `PROC_IF_STATE_EXTRA_FETCH_SET; end else begin /* Both on this address! */ - ProgCount=ProgCount+2; + ProgCount <= ProgCount+2; CIR <= {external_data_bus[7:0],external_data_bus[15:8]}; - state=`PROC_DE_STATE_ENTRY; + state <= `PROC_DE_STATE_ENTRY; end end end `PROC_IF_STATE_EXTRA_FETCH_SET:begin - external_address_bus = ProgCount; - BHE=0; - state=`PROC_IF_STATE_EXTRA_FETCH; + external_address_bus <= {4'b0,ProgCount}; + BHE <= 0; + state <= `PROC_IF_STATE_EXTRA_FETCH; end `PROC_IF_STATE_EXTRA_FETCH:begin CIR[7:0] <= external_data_bus[7:0]; - ProgCount=ProgCount+1; - state=`PROC_DE_STATE_ENTRY; + ProgCount <= ProgCount+1; + state <= `PROC_DE_STATE_ENTRY; end `PROC_DE_STATE_ENTRY:begin - external_address_bus = ProgCount; + external_address_bus <= {4'b0,ProgCount}; if(SIMPLE_MICRO==0)begin /*This flag is set at reset and jump because * at IF we need to know the size of the @@ -269,110 +274,110 @@ always @(posedge clock) begin * incorrect in both cases. So when it gets * set reset it only at the start of the next * 8086 instruction */ - instruction_size_init=0; + instruction_size_init <= 0; /* We cannot set these directly within * microcode so don't overwrite useful values * each time the next microcode is executed. * Note this still allows to set initial values * at the start of the microcode */ - PARAM1=DE_PARAM1; - PARAM2=DE_PARAM2; + PARAM1 <= DE_PARAM1; + PARAM2 <= DE_PARAM2; end - ERROR=DE_ERROR; - HALT=DE_HALT; - reg_read_port1_addr=DE_reg_read_port1_addr; - reg_read_port2_addr=DE_reg_read_port2_addr; - reg_write_addr=DE_reg_write_addr; + ERROR <= DE_ERROR; + HALT <= DE_HALT; + reg_read_port1_addr <= DE_reg_read_port1_addr; + reg_read_port2_addr <= DE_reg_read_port2_addr; + reg_write_addr <= DE_reg_write_addr; 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; + 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 - state=next_state; + state <= next_state; end end `PROC_DE_LOAD_REG_TO_PARAM:begin - PARAM2=reg_read_port2_data; + PARAM2<=reg_read_port2_data; case(IN_MOD) - 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; - default: state=`PROC_EX_STATE_ENTRY; + 3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; + default: state <= `PROC_EX_STATE_ENTRY; endcase end `PROC_DE_LOAD_8_PARAM:begin if(opcode_size==0)begin if({Sbit,Wbit}==2'b11)begin /*signed "16bit" read*/ - PARAM1 = {{8{CIR[7:7]}},CIR[7:0]}; + PARAM1 <= {{8{CIR[7:7]}},CIR[7:0]}; end else begin - PARAM1[7:0] = CIR[7:0]; + PARAM1[7:0] <= CIR[7:0]; end case(IN_MOD) - 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; - default: state=`PROC_EX_STATE_ENTRY; + 3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; + default: state <= `PROC_EX_STATE_ENTRY; endcase end else begin if(ProgCount[0:0]==1)begin if({Sbit,Wbit}==2'b11)begin /*signed "16bit" read*/ - PARAM1 = {{8{external_data_bus[15:15]}},external_data_bus[15:8]}; + PARAM1 <= {{8{external_data_bus[15:15]}},external_data_bus[15:8]}; end else begin - PARAM1[7:0] = external_data_bus[15:8]; + PARAM1[7:0] <= external_data_bus[15:8]; end end else begin if({Sbit,Wbit}==2'b11)begin /*signed "16bit" read*/ - PARAM1 = {{8{external_data_bus[7:7]}},external_data_bus[7:0]}; + PARAM1 <= {{8{external_data_bus[7:7]}},external_data_bus[7:0]}; end else begin - PARAM1[7:0] = external_data_bus[7:0]; + PARAM1[7:0] <= external_data_bus[7:0]; end end - ProgCount=ProgCount+1; + ProgCount <= ProgCount+1; case(IN_MOD) - 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; - default: state=`PROC_EX_STATE_ENTRY; + 3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; + default: state <= `PROC_EX_STATE_ENTRY; endcase end end `PROC_DE_LOAD_16_PARAM:begin if(opcode_size==0)begin - PARAM1[7:0] = CIR[7:0]; + PARAM1[7:0] <= CIR[7:0]; if(ProgCount[0:0]==1)begin - PARAM1[15:8] = external_data_bus[15:8]; + PARAM1[15:8] <= external_data_bus[15:8]; end else begin - PARAM1[15:8] = external_data_bus[7:0]; + PARAM1[15:8] <= external_data_bus[7:0]; end - ProgCount=ProgCount+1; + ProgCount <= ProgCount+1; case(IN_MOD) - 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; - default: state=`PROC_EX_STATE_ENTRY; + 3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; + default: state <= `PROC_EX_STATE_ENTRY; endcase end else begin if(ProgCount[0:0]==1)begin - ProgCount=ProgCount+1; - PARAM1[7:0] = external_data_bus[15:8]; - state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET; + ProgCount <= ProgCount+1; + PARAM1[7:0] <= external_data_bus[15:8]; + state <= `PROC_DE_LOAD_16_EXTRA_FETCH_SET; end else begin - PARAM1 = external_data_bus; - ProgCount=ProgCount+2; + PARAM1 <= external_data_bus; + ProgCount <= ProgCount+2; case(IN_MOD) - 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; - default: state=`PROC_EX_STATE_ENTRY; + 3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; + default: state <= `PROC_EX_STATE_ENTRY; endcase end end end `PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin - external_address_bus = ProgCount; - state=`PROC_DE_LOAD_16_EXTRA_FETCH; + external_address_bus <= {4'b0,ProgCount}; + state <= `PROC_DE_LOAD_16_EXTRA_FETCH; end `PROC_DE_LOAD_16_EXTRA_FETCH:begin - ProgCount=ProgCount+1; - PARAM1[15:8] = external_data_bus[7:0]; + ProgCount <= ProgCount+1; + PARAM1[15:8] <= external_data_bus[7:0]; case(IN_MOD) - 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; - default: state=`PROC_EX_STATE_ENTRY; + 3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; + default: state <= `PROC_EX_STATE_ENTRY; endcase end `PROC_MEMIO_READ:begin @@ -400,13 +405,13 @@ always @(posedge clock) begin end 3'b100:begin /*[SI]*/ - reg_read_port1_addr=4'b1110; - state=`PROC_MEMIO_READ_SETADDR; + reg_read_port1_addr <= 4'b1110; + state <= `PROC_MEMIO_READ_SETADDR; end 3'b101:begin /*[DI]*/ - reg_read_port1_addr=4'b1111; - state=`PROC_MEMIO_READ_SETADDR; + reg_read_port1_addr <= 4'b1111; + state <= `PROC_MEMIO_READ_SETADDR; end 3'b110:begin /*d16 */ @@ -414,8 +419,8 @@ always @(posedge clock) begin end 3'b111:begin /*[BX]*/ - reg_read_port1_addr=4'b1011; - state=`PROC_MEMIO_READ_SETADDR; + reg_read_port1_addr <= 4'b1011; + state <= `PROC_MEMIO_READ_SETADDR; end endcase if(IN_MOD!=3'b000)begin @@ -424,8 +429,8 @@ always @(posedge clock) begin end end 3'b110:begin /* SP Indirect read*/ - reg_read_port1_addr=4'b1100; - state=`PROC_MEMIO_READ_SETADDR; + reg_read_port1_addr <= 4'b1100; + state <= `PROC_MEMIO_READ_SETADDR; end default:begin `invalid_instruction @@ -433,32 +438,32 @@ always @(posedge clock) begin endcase end `PROC_MEMIO_READ_SETADDR:begin - external_address_bus = {5'b0000,reg_read_port1_data[15:0]}; - state=reg_read_port1_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA; + external_address_bus <= {4'b0,reg_read_port1_data[15:0]}; + state <= reg_read_port1_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA; end `PROC_MEMIO_GET_ALIGNED_DATA:begin - PARAM2=(Wbit==1)? external_data_bus : {8'b00000000,external_data_bus[7:0]} ; - state=`PROC_EX_STATE_ENTRY; + PARAM2 <= (Wbit==1)? external_data_bus : {8'b0,external_data_bus[7:0]} ; + state <= `PROC_EX_STATE_ENTRY; end `PROC_MEMIO_GET_UNALIGNED_DATA:begin - PARAM2={8'b00000000,external_data_bus[15:8]}; + PARAM2 <= {8'b0,external_data_bus[15:8]}; if(Wbit==1) begin - state=`PROC_MEMIO_GET_SECOND_BYTE; + state <= `PROC_MEMIO_GET_SECOND_BYTE; end else begin - state=`PROC_EX_STATE_ENTRY; + state <= `PROC_EX_STATE_ENTRY; end end `PROC_MEMIO_GET_SECOND_BYTE:begin - external_address_bus=external_address_bus+1; - state=`PROC_MEMIO_GET_SECOND_BYTE1; + external_address_bus <= external_address_bus+1; + state <= `PROC_MEMIO_GET_SECOND_BYTE1; end `PROC_MEMIO_GET_SECOND_BYTE1:begin - PARAM2[15:8]=external_data_bus[7:0]; - state=`PROC_EX_STATE_ENTRY; + PARAM2[15:8] <= external_data_bus[7:0]; + state <= `PROC_EX_STATE_ENTRY; end `PROC_EX_STATE_ENTRY:begin - external_address_bus = ProgCount; - FLAGS[7:0] = ALU_1FLAGS[7:0]; + external_address_bus <= {4'b0,ProgCount}; + FLAGS[7:0] <= ALU_1FLAGS[7:0]; case(OUT_MOD) 3'b000, 3'b001, @@ -482,13 +487,13 @@ always @(posedge clock) begin end 3'b100:begin /*[SI]*/ - reg_read_port1_addr=4'b1110; - state=`PROC_MEMIO_WRITE; + reg_read_port1_addr <= 4'b1110; + state <= `PROC_MEMIO_WRITE; end 3'b101:begin /*[DI]*/ - reg_read_port1_addr=4'b1111; - state=`PROC_MEMIO_WRITE; + reg_read_port1_addr <= 4'b1111; + state <= `PROC_MEMIO_WRITE; end 3'b110:begin /*d16 */ @@ -496,35 +501,35 @@ always @(posedge clock) begin end 3'b111:begin /*[BX]*/ - reg_read_port1_addr=4'b1011; - state=`PROC_MEMIO_WRITE; + reg_read_port1_addr <= 4'b1011; + state <= `PROC_MEMIO_WRITE; end endcase end 3'b011:begin - reg_write_we=0; + reg_write_we <= 0; if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) - state=`PROC_IF_STATE_ENTRY; + state <= `PROC_IF_STATE_ENTRY; else - state=`PROC_NEXT_MICROCODE; + state <= `PROC_NEXT_MICROCODE; end 3'b100:begin /*No output*/ if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) - state=`PROC_IF_STATE_ENTRY; + state <= `PROC_IF_STATE_ENTRY; else - state=`PROC_NEXT_MICROCODE; + state <= `PROC_NEXT_MICROCODE; end 3'b101:begin /* Program Counter*/ - ProgCount={5'b0000,ALU_1O[15:0]}; - instruction_size_init=1; + ProgCount <= ALU_1O[15:0]; + instruction_size_init <= 1; if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) - state=`PROC_IF_STATE_ENTRY; + state <= `PROC_IF_STATE_ENTRY; else - state=`PROC_NEXT_MICROCODE; + state <= `PROC_NEXT_MICROCODE; end 3'b110:begin /* SP Indirect write*/ - reg_read_port1_addr=4'b1100; - state=`PROC_MEMIO_WRITE; + reg_read_port1_addr <= 4'b1100; + state <= `PROC_MEMIO_WRITE; end default:begin `invalid_instruction @@ -536,65 +541,66 @@ always @(posedge clock) begin `ifdef DEBUG_MEMORY_WRITES $display("Writing at %04x , %04x",reg_read_port1_data,ALU_1O); `endif - external_address_bus = {5'b0000,reg_read_port1_data[15:0]}; - state = (Wbit==0) ? `PROC_MEMIO_PUT_BYTE : (reg_read_port1_data[0:0]?`PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA:`PROC_MEMIO_PUT_ALIGNED_16BIT_DATA) ; + external_address_bus <= {4'b0,reg_read_port1_data[15:0]}; + state <= (Wbit==0) ? `PROC_MEMIO_PUT_BYTE : (reg_read_port1_data[0:0]?`PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA:`PROC_MEMIO_PUT_ALIGNED_16BIT_DATA) ; end `PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA:begin - read=1; - BHE=0; - data_bus_output_register={ALU_1O[7:0],ALU_1O[15:8]}; - state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT; + read <= 1; + BHE <= 0; + data_bus_output_register <= {ALU_1O[7:0],ALU_1O[15:8]}; + state <= `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT; end `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT:begin - write=0; - state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2; + write <= 0; + state <= `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2; end `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2:begin - write=1; - external_address_bus=external_address_bus+1; - BHE=1; - state=`PROC_MEMIO_WRITE_EXIT; + write <= 1; + external_address_bus <= external_address_bus+1; + BHE <= 1; + state <= `PROC_MEMIO_WRITE_EXIT; end `PROC_MEMIO_PUT_ALIGNED_16BIT_DATA:begin - read=1; - data_bus_output_register={ALU_1O[15:8],ALU_1O[7:0]}; - state=`PROC_MEMIO_WRITE_EXIT; + read <= 1; + data_bus_output_register <= {ALU_1O[15:8],ALU_1O[7:0]}; + state <= `PROC_MEMIO_WRITE_EXIT; end `PROC_MEMIO_PUT_BYTE:begin - read=1; - state=`PROC_MEMIO_WRITE_EXIT; + read <= 1; + state <= `PROC_MEMIO_WRITE_EXIT; if(reg_read_port1_data[0:0]==0) begin - BHE=1; - data_bus_output_register={8'b0,ALU_1O[7:0]}; + BHE <= 1; + data_bus_output_register <= {8'b0,ALU_1O[7:0]}; end else begin - data_bus_output_register={ALU_1O[7:0],8'b0}; + data_bus_output_register <= {ALU_1O[7:0],8'b0}; end end `PROC_MEMIO_WRITE_EXIT:begin - write=0; + write <= 0; if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) - state=`PROC_IF_STATE_ENTRY; + state <= `PROC_IF_STATE_ENTRY; else - state=`PROC_NEXT_MICROCODE; + state <= `PROC_NEXT_MICROCODE; end `PROC_NEXT_MICROCODE:begin - read=0; - write=1; // maybe we are coming from MEMIO_WRITE - BHE=0; - ucode_seq_addr=ucode_seq_addr_entry; /*Reused for next address*/ - if( ucode_seq_addr == `UCODE_NO_INSTRUCTION )begin + read <= 0; + write <= 1; // maybe we are coming from MEMIO_WRITE + BHE <= 0; + ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ + if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin /*Finished microcode*/ - SIMPLE_MICRO=0; - state=`PROC_IF_STATE_ENTRY; + SIMPLE_MICRO <= 0; + state <= `PROC_IF_STATE_ENTRY; end else begin - state=`PROC_DE_STATE_ENTRY; + state <= `PROC_DE_STATE_ENTRY; end - reg_write_we=1; + reg_write_we <= 1; end default:begin end endcase end +`undef invalid_instruction endmodule diff --git a/system/registers.v b/system/registers.v index c527fc1..80552c4 100644 --- a/system/registers.v +++ b/system/registers.v @@ -34,11 +34,11 @@ reg [15:0] registers [7:0]; assign read_port1_data[15:8] = read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][15:8] : 8'hz ; assign read_port1_data[7:0] = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][7:0] : - ( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[1:0]][15:8]} : {8'b0,registers[read_port1_addr[1:0]][7:0]} ) ); + ( read_port1_addr[2:2] ? registers[ {1'b0,read_port1_addr[1:0]} ][15:8] : registers[ {1'b0,read_port1_addr[1:0]} ][7:0] ) ); assign read_port2_data[15:8] = read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][15:8] : 8'hz ; assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][7:0] : - ( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[1:0]][15:8]} : {8'b0,registers[read_port2_addr[1:0]][7:0]} ) ); + ( read_port2_addr[2:2] ? registers[ {1'b0,read_port2_addr[1:0]} ][15:8] : registers[ {1'b0,read_port2_addr[1:0]} ][7:0] ) ); `ifdef DEBUG_REG_WRITES string debug_name; @@ -50,15 +50,15 @@ assign write_Wbit=write_port1_addr[3:3]; always @(negedge write_port1_we) begin if(write_Wbit==1)begin /* Word : AX,CX,DX,BX,SP,BP,SI,DI */ - registers[write_port1_addr[2:0]]=write_port1_data; + registers[write_port1_addr[2:0]] <= write_port1_data; end else begin /* Byte : AL,CL,DL,BL,AX,CX,DX,BX */ if(write_port1_addr[2:2]==1)begin /* Byte */ - registers[write_port1_addr[1:0]][15:8]=write_port1_data[7:0]; + registers[ {1'b0,write_port1_addr[1:0]} ][15:8] <= write_port1_data[7:0]; end else begin /* Byte */ - registers[write_port1_addr[1:0]][7:0]=write_port1_data[7:0]; + registers[ {1'b0,write_port1_addr[1:0]} ][7:0] <= write_port1_data[7:0]; end end diff --git a/system/testbench.v b/system/testbench.v index 6271307..1352180 100644 --- a/system/testbench.v +++ b/system/testbench.v @@ -46,10 +46,12 @@ initial begin $dumpfile(waveform_name); $dumpvars(0,p,u1); end - reset = 0; clk_enable = 1; - #($random%500) + reset = 1; + #(`CPU_SPEED*2) + reset = 0; + #($random%1000) #(`CPU_SPEED) reset = 1; end @@ -76,6 +78,8 @@ end always @(posedge clock)begin if(reset==1) cycles=cycles+1; + else + cycles=0; end endmodule diff --git a/system/ucode_header.v b/system/ucode_header.v index 3c3141a..3ac1a28 100644 --- a/system/ucode_header.v +++ b/system/ucode_header.v @@ -17,14 +17,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -`define UCODE_ADDR_BITS 5 -`define UCODE_DATA_BITS 38 `define UCODE_SIZE 12 +`define UCODE_DATA_BITS 38 +`define UCODE_ADDR_BITS $clog2(`UCODE_SIZE) /* DEFINE ADDRESSES IN THE MICROCODE */ -`define UCODE_NO_INSTRUCTION 5'b00000 -`define UCODE_CALL_ENTRY 5'b00001 -`define UCODE_RET_ENTRY 5'b00100 -`define UCODE_STOS_ENTRY 5'b00110 -`define UCODE_PUSH_ENTRY 5'b01000 -`define UCODE_POP_ENTRY 5'b01010 +`define UCODE_NO_INSTRUCTION 4'b0000 +`define UCODE_CALL_ENTRY 4'b0001 +`define UCODE_RET_ENTRY 4'b0100 +`define UCODE_STOS_ENTRY 4'b0110 +`define UCODE_PUSH_ENTRY 4'b1000 +`define UCODE_POP_ENTRY 4'b1010