Compare commits

..

No commits in common. "ba52ff89e6ea10c55a6eb154b2e9416652fd45b8" and "b00cd988cf0fa4abb6e940c36755b9833af9f18d" have entirely different histories.

7 changed files with 278 additions and 289 deletions

View File

@ -26,7 +26,7 @@ wire signed [7:0]SIGNED_8B;
assign SIGNED_B=B; assign SIGNED_B=B;
assign SIGNED_8B=B[7:0]; 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'b0,C_FLAG}; assign FLAGS={(Wbit==1)?OUT[15:15]:OUT[7:7],(Wbit==1) ? (OUT[15:0]=='h0000) : (OUT[7:0]=='h00),5'b00000,C_FLAG};
always @ ( * ) begin always @ ( * ) begin
if(Wbit==1)begin if(Wbit==1)begin
@ -35,9 +35,9 @@ always @ ( * ) begin
`ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT}=A+SIGNED_B; `ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT}=A+SIGNED_B;
`ALU_OP_SUB: {C_FLAG,OUT}=A-B; `ALU_OP_SUB: {C_FLAG,OUT}=A-B;
`ALU_OP_SUB_REVERSE: {C_FLAG,OUT}=B-A; `ALU_OP_SUB_REVERSE: {C_FLAG,OUT}=B-A;
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end `ALU_OP_AND: OUT=A&B;
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end `ALU_OP_OR: OUT=A|B;
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end `ALU_OP_XOR: OUT=A^B;
default:begin default:begin
OUT=0; OUT=0;
C_FLAG=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_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: {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_SUB_REVERSE: {C_FLAG,OUT[7:0]}=B[7:0]-A[7:0];
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end `ALU_OP_AND: OUT=A&B;
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end `ALU_OP_OR: OUT=A|B;
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end `ALU_OP_XOR: OUT=A^B;
default:begin default:begin
OUT=0; OUT=0;
C_FLAG=0; C_FLAG=0;

View File

@ -29,22 +29,21 @@ module microcode(
initial begin initial begin
string ucode_path; string ucode_path;
if($value$plusargs("MICROCODE=%s",ucode_path))begin if($value$plusargs("MICROCODE=%s",ucode_path))begin
$readmemb(ucode_path,ucode_rom,0,`UCODE_SIZE-1); $readmemb(ucode_path,ucode,0,`UCODE_SIZE-1);
end else begin end else begin
$display("Please supply microcode rom file as a runtime vvp argument +MICROCODE=<path>"); $display("Please supply microcode rom file as a runtime vvp argument +MICROCODE=<path>");
$finish; $finish;
end end
end end
reg [`UCODE_DATA_BITS-1:0] ucode_rom [ 0:`UCODE_SIZE-1 ]; reg [`UCODE_DATA_BITS-1:0] ucode [ 0:`UCODE_SIZE-1 ];
assign DATA=ucode_rom[ADDR]; assign DATA=ucode[ADDR];
endmodule endmodule
// verilator lint_off UNUSEDSIGNAL
module decoder( 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 input wire [15:0] CIR,input wire [15:0] FLAGS, output wire [3: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 ,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_alu1_sel1,output reg [1:0]in_alu1_sel2,output reg [2:0]OUT_MOD ,output reg [1:0]in_alu1_sel1,output reg [1:0]in_alu1_sel2,output reg [2:0]OUT_MOD
,output wire [11:0]REGISTER_FILE_CONTROL ,output wire [11:0]REGISTER_FILE_CONTROL
@ -52,7 +51,6 @@ 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 [`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 ,output reg [2:0]instruction_size
); );
// verilator lint_on UNUSEDSIGNAL
reg [3:0]reg_read_port1_addr; reg [3:0]reg_read_port1_addr;
reg [3:0]reg_read_port2_addr; reg [3:0]reg_read_port2_addr;
@ -60,49 +58,45 @@ reg [3:0]reg_write_addr;
assign REGISTER_FILE_CONTROL={reg_write_addr,reg_read_port1_addr,reg_read_port2_addr}; assign REGISTER_FILE_CONTROL={reg_write_addr,reg_read_port1_addr,reg_read_port2_addr};
/* For correct fetching of instructions and global options for the alu */ /* For correct fetching of instructions and global options for the alu */
reg Wbit,Sbit,opcode_size; reg Wbit,Sbit,unaligning,opcode_size;
assign INSTRUCTION_INFO={Wbit,Sbit,opcode_size}; assign INSTRUCTION_INFO={Wbit,Sbit,unaligning,opcode_size};
reg ERROR, HALT; reg ERROR, HALT;
assign DECODER_SIGNALS={ERROR,HALT}; assign DECODER_SIGNALS={ERROR,HALT};
// verilator lint_off UNUSEDSIGNAL
wire [`UCODE_DATA_BITS-1:0] ucode_data; wire [`UCODE_DATA_BITS-1:0] ucode_data;
// verilator lint_on UNUSEDSIGNAL reg [`UCODE_ADDR_BITS-1:0] UCODE_ADDR;
microcode ucode(seq_addr_input,ucode_data); 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 */ /* 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=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION; `define invalid_instruction next_state=`PROC_IF_STATE_ENTRY;ERROR=1;IN_MOD=2'b11;
`define start_aligning_instruction unaligning=0;
`define start_unaligning_instruction unaligning=1;
//TODO: A possible optimisation for instruction with 8bit parameter and //TODO: A possible optimisation for instruction with 8bit parameter and
//opcode_size=0 would be to set PARAM1 here instead of sending execution over //opcode_size=0 would be to set PARAM1 here instead of sending execution over
//to PROC_DE_LOAD_8_PARAM //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 always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
if (SIMPLE_MICRO==0)begin if (SIMPLE_MICRO==0)begin
casez({CIR[15:8],CIR[5:3]}) ERROR=0;HALT=0;seq_addr_entry=`UCODE_NO_INSTRUCTION;
11'b0000_010?_??? : begin casex({CIR[15:8],CIR[5:3]})
11'b0000_010x_xxx : begin
/* ADD - Add Immediate word/byte to accumulator */ /* ADD - Add Immediate word/byte to accumulator */
/* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/ /* 0 0 0 0 0 1 0 W | DATA | DATA if W |*/
opcode_size=0; opcode_size=0;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
if(Wbit)begin if(Wbit)begin
`start_unaligning_instruction
instruction_size=3; instruction_size=3;
end else begin end else begin
`start_aligning_instruction
instruction_size=2; instruction_size=2;
end end
IN_MOD=3'b011; IN_MOD=2'b11;
in_alu1_sel1=2'b00; in_alu1_sel1=2'b00;
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
OUT_MOD=3'b011; OUT_MOD=3'b011;
@ -113,10 +107,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
next_state=`PROC_DE_LOAD_16_PARAM; next_state=`PROC_DE_LOAD_16_PARAM;
else else
next_state=`PROC_DE_LOAD_8_PARAM; next_state=`PROC_DE_LOAD_8_PARAM;
`normal_instruction;
end end
11'b1000_00??_101, /* SUB */ 11'b1000_00xx_101, /* SUB */
11'b1000_00??_000 : /* ADD */ begin 11'b1000_00xx_000 : /* ADD */ begin
/* ADD - Add Immediate word/byte to register/memory */ /* 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 | */ /* 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 */ /* SUB - Subtract immediate word/byte from register/memory */
@ -124,23 +117,25 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
opcode_size=1; opcode_size=1;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
Sbit=CIR[9:9]; Sbit=CIR[9:9];
IN_MOD={1'b0,CIR[7:6]}; IN_MOD=CIR[7:6];
RM=CIR[2:0]; RM=CIR[2:0];
in_alu1_sel1=2'b00; in_alu1_sel1=2'b00;
if(IN_MOD==3'b011)begin if(IN_MOD==2'b11)begin
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
reg_write_addr={Wbit,RM}; reg_write_addr={Wbit,RM};
end else begin end else begin
in_alu1_sel2=2'b00; in_alu1_sel2=2'b00;
end end
OUT_MOD=IN_MOD; OUT_MOD={1'b0,IN_MOD};
case({Sbit,Wbit}) case({Sbit,Wbit})
2'b00,2'b11:begin 2'b00,2'b11:begin
`start_unaligning_instruction
next_state=`PROC_DE_LOAD_8_PARAM; next_state=`PROC_DE_LOAD_8_PARAM;
instruction_size=3; instruction_size=3;
end end
2'b01:begin 2'b01:begin
`start_aligning_instruction
next_state=`PROC_DE_LOAD_16_PARAM; next_state=`PROC_DE_LOAD_16_PARAM;
instruction_size=4; instruction_size=4;
end end
@ -156,22 +151,23 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
`invalid_instruction `invalid_instruction
end end
endcase endcase
`normal_instruction;
end end
11'b1000_00??_111 : begin 11'b1000_00xx_111 : begin
/* CMP - compare Immediate with register / memory */ /* 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 | */ /* 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; opcode_size=1;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
Sbit=CIR[9:9]; Sbit=CIR[9:9];
IN_MOD={1'b0,CIR[7:6]}; IN_MOD=CIR[7:6];
RM=CIR[2:0]; RM=CIR[2:0];
case({Sbit,Wbit}) case({Sbit,Wbit})
2'b00,2'b11:begin 2'b00,2'b11:begin
instruction_size=3; instruction_size=3;
`start_unaligning_instruction
end end
2'b01:begin 2'b01:begin
instruction_size=4; instruction_size=4;
`start_aligning_instruction
end end
2'b10:begin 2'b10:begin
`invalid_instruction `invalid_instruction
@ -180,7 +176,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
in_alu1_sel1=2'b00; in_alu1_sel1=2'b00;
OUT_MOD=3'b100; OUT_MOD=3'b100;
ALU_1OP=`ALU_OP_SUB; ALU_1OP=`ALU_OP_SUB;
if(IN_MOD==3'b011)begin if(IN_MOD==2'b11)begin
/*compare register with param*/ /*compare register with param*/
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
@ -191,15 +187,15 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
in_alu1_sel2=2'b00; in_alu1_sel2=2'b00;
next_state=`PROC_DE_LOAD_16_PARAM; /*will the call MEMIO_READ*/ next_state=`PROC_DE_LOAD_16_PARAM; /*will the call MEMIO_READ*/
end end
`normal_instruction;
end end
11'b1011_0???_??? : begin 11'b1011_0xxx_xxx : begin
/* MOV - Move Immediate byte to register */ /* MOV - Move Immediate byte to register */
/* 1 0 1 1 W REG | DATA | DATA if W |*/ /* 1 0 1 1 W REG | DATA | DATA if W |*/
`start_aligning_instruction
Wbit=CIR[11:11]; /* IS 0 */ Wbit=CIR[11:11]; /* IS 0 */
instruction_size=2; instruction_size=2;
opcode_size=0; opcode_size=0;
IN_MOD=3'b011; IN_MOD=2'b11;
in_alu1_sel1=2'b00; in_alu1_sel1=2'b00;
in_alu1_sel2=2'b00; in_alu1_sel2=2'b00;
OUT_MOD=3'b011; OUT_MOD=3'b011;
@ -208,14 +204,14 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM2=0; PARAM2=0;
ALU_1OP=`ALU_OP_ADD; ALU_1OP=`ALU_OP_ADD;
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
`normal_instruction;
end end
11'b1011_1???_??? : begin 11'b1011_1xxx_xxx : begin
/*MOV - Move Immediate word to register*/ /*MOV - Move Immediate word to register*/
`start_unaligning_instruction
Wbit=CIR[11:11]; /*IS 1 */ Wbit=CIR[11:11]; /*IS 1 */
instruction_size=3; instruction_size=3;
opcode_size=0; opcode_size=0;
IN_MOD=3'b011; IN_MOD=2'b11;
in_alu1_sel1=2'b00; in_alu1_sel1=2'b00;
in_alu1_sel2=2'b00; in_alu1_sel2=2'b00;
OUT_MOD=3'b011; OUT_MOD=3'b011;
@ -223,11 +219,12 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_1OP=`ALU_OP_ADD; ALU_1OP=`ALU_OP_ADD;
PARAM2=0; PARAM2=0;
next_state=`PROC_DE_LOAD_16_PARAM; next_state=`PROC_DE_LOAD_16_PARAM;
`normal_instruction;
end end
11'b1000_10??_??? : begin
11'b1000_10xx_xxx : begin
/* MOV - Reg/Mem to/from register */ /* MOV - Reg/Mem to/from register */
/* 1 0 0 0 1 0 D W | MOD REG RM | < DISP LO > | < DISP HI > |*/ /* 1 0 0 0 1 0 D W | MOD REG RM | < DISP LO > | < DISP HI > |*/
`start_aligning_instruction
opcode_size=1; opcode_size=1;
instruction_size=2; instruction_size=2;
RM=CIR[2:0]; RM=CIR[2:0];
@ -237,7 +234,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
if(CIR[9:9] == 1)begin if(CIR[9:9] == 1)begin
/* Mem/Reg to reg */ /* Mem/Reg to reg */
IN_MOD={1'b0,CIR[7:6]}; IN_MOD={1'b0,CIR[7:6]};
if(IN_MOD==3'b011)begin if(IN_MOD==2'b11)begin
/*Reg to Reg*/ /*Reg to Reg*/
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
@ -253,7 +250,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* Reg to Mem/Reg */ /* Reg to Mem/Reg */
IN_MOD=3'b011; IN_MOD=3'b011;
OUT_MOD={1'b0,CIR[7:6]}; OUT_MOD={1'b0,CIR[7:6]};
if(IN_MOD==3'b011)begin if(IN_MOD==2'b11)begin
/*Reg to Reg*/ /*Reg to Reg*/
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_write_addr={Wbit,RM}; reg_write_addr={Wbit,RM};
@ -265,22 +262,22 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end end
reg_read_port2_addr={Wbit,CIR[5:3]}; reg_read_port2_addr={Wbit,CIR[5:3]};
end end
ALU_1OP=`ALU_OP_ADD;
`normal_instruction; ALU_1OP=`ALU_OP_ADD;
end end
11'b0100_????_???:begin//DEC 11'b0100_xxxx_xxx:begin//DEC
/* DEC - Decrement Register */ /* DEC - Decrement Register */
/* | 0 1 0 0 1 REG | */ /* | 0 1 0 0 1 REG | */
/* INC - Increment Register */ /* INC - Increment Register */
/* | 0 1 0 0 0 REG | */ /* | 0 1 0 0 0 REG | */
instruction_size=1; instruction_size=1;
opcode_size=0; opcode_size=0;
`start_unaligning_instruction
Wbit=1; Wbit=1;
in_alu1_sel1=2'b01; in_alu1_sel1=2'b01;
in_alu1_sel2=2'b00; in_alu1_sel2=2'b00;
OUT_MOD=3'b011; OUT_MOD=3'b011;
IN_MOD=3'b011; IN_MOD=2'b11;
PARAM2=1; PARAM2=1;
reg_read_port1_addr={1'b1,CIR[10:8]}; reg_read_port1_addr={1'b1,CIR[10:8]};
reg_write_addr={1'b1,CIR[10:8]}; reg_write_addr={1'b1,CIR[10:8]};
@ -289,47 +286,44 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
else else
ALU_1OP=`ALU_OP_SUB; ALU_1OP=`ALU_OP_SUB;
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
`normal_instruction;
end end
11'b1111_111?_00? : begin 11'b1111_111x_00x : begin
/* INC - Register/Memory */ /* INC - Register/Memory */
/* 1 1 1 1 1 1 1 W | MOD 0 0 0 R/M | < DISP LO> | < DISP HI> */ /* 1 1 1 1 1 1 1 W | MOD 0 0 0 R/M | < DISP LO> | < DISP HI> */
/* DEC - Register/Memory */ /* DEC - Register/Memory */
/* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */ /* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */
instruction_size=2; instruction_size=2;
opcode_size=1; opcode_size=1;
`start_aligning_instruction
Wbit=CIR[8:8]; Wbit=CIR[8:8];
IN_MOD={1'b0,CIR[7:6]}; IN_MOD=CIR[7:6];
RM=CIR[2:0]; RM=CIR[2:0];
in_alu1_sel2=(IN_MOD==3'b011)? 2'b01 : 2'b00; in_alu1_sel2=(IN_MOD==2'b11)? 2'b01 : 2'b00;
in_alu1_sel1=2'b00;/* number 1 */ in_alu1_sel1=2'b00;/* number 1 */
PARAM1=1; PARAM1=1;
OUT_MOD=IN_MOD; OUT_MOD={1'b0,IN_MOD};
/*in case IN_MOD=011 */ /*in case IN_MOD=11 */
reg_read_port2_addr={1'b0,RM}; reg_read_port2_addr={1'b0,RM};
reg_write_addr={1'b0,RM}; reg_write_addr={1'b0,RM};
ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD; ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD;
if ( IN_MOD == 3'b011 ) if ( IN_MOD == 2'b11 )
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
else else
next_state=`PROC_MEMIO_READ; next_state=`PROC_MEMIO_READ;
`normal_instruction;
end end
11'b1111_0100_??? : begin 11'b1111_0100_xxx : begin
/* HLT - Halt */ /* HLT - Halt */
/* 1 1 1 1 0 1 0 0 | */ /* 1 1 1 1 0 1 0 0 | */
instruction_size=1; instruction_size=1;
opcode_size=0; opcode_size=0;
IN_MOD=3'b011; `start_unaligning_instruction
HALT<=1; IN_MOD=2'b11;
ERROR<=0; HALT=1;
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
next_state=`PROC_HALT_STATE; next_state=`PROC_HALT_STATE;
end end
11'b0011_110?_??? : begin 11'b0011_110x_xxx : begin
/* CMP - Compare Immediate with accumulator */ /* CMP - Compare Immediate with accumulator */
/* 0 0 1 1 1 1 0 W | DATA | DATA if W |*/ /* 0 0 1 1 1 1 0 W | DATA | DATA if W |*/
/* */ /* */
@ -339,10 +333,12 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
opcode_size=0; opcode_size=0;
if(Wbit)begin if(Wbit)begin
instruction_size=3; instruction_size=3;
`start_unaligning_instruction
end else begin end else begin
instruction_size=2; instruction_size=2;
`start_aligning_instruction
end end
IN_MOD=3'b011; IN_MOD=2'b11;
in_alu1_sel1=2'b00; in_alu1_sel1=2'b00;
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,3'b000}; reg_read_port2_addr={Wbit,3'b000};
@ -354,9 +350,8 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
PARAM1[7:0]=CIR[7:0]; PARAM1[7:0]=CIR[7:0];
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
end end
`normal_instruction;
end end
11'b0111_????_???:begin 11'b0111_xxxx_xxx:begin
/* Conditional relative jumps */ /* Conditional relative jumps */
/* JE/JZ - Jump on Zero */ /* JE/JZ - Jump on Zero */
/* 0 1 1 1 0 1 0 0 | IP-INC8 |*/ /* 0 1 1 1 0 1 0 0 | IP-INC8 |*/
@ -366,6 +361,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* 0 1 1 1 1 0 0 1 | IP-INC8 |*/ /* 0 1 1 1 1 0 0 1 | IP-INC8 |*/
/* .... */ /* .... */
instruction_size=2; instruction_size=2;
`start_aligning_instruction
Wbit=1; Wbit=1;
opcode_size=0; opcode_size=0;
in_alu1_sel1=2'b10; in_alu1_sel1=2'b10;
@ -407,11 +403,11 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
`invalid_instruction; /*We don't support that condition*/ `invalid_instruction; /*We don't support that condition*/
end end
endcase endcase
`normal_instruction;
end end
11'b1110_1011_???:begin 11'b1110_1011_xxx:begin
/* JMP - Unconditional jump direct within segment (short) */ /* JMP - Unconditional jump direct within segment (short) */
/* | 1 1 1 0 1 0 1 1 | IP-INC-LO | */ /* | 1 1 1 0 1 0 1 1 | IP-INC-LO | */
`start_aligning_instruction
instruction_size=2; instruction_size=2;
opcode_size=0; opcode_size=0;
Wbit=1; Wbit=1;
@ -421,67 +417,70 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
ALU_1OP=`ALU_OP_ADD_SIGNED_B; ALU_1OP=`ALU_OP_ADD_SIGNED_B;
OUT_MOD=3'b101; OUT_MOD=3'b101;
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
`normal_instruction;
end end
11'b1100_1101_???:begin 11'b1100_1101_xxx:begin
/* INT - execute interrupt handler */ /* INT - execute interrupt handler */
/* 1 1 0 0 1 1 0 1 | DATA |*/ /* 1 1 0 0 1 1 0 1 | DATA |*/
instruction_size=2; instruction_size=2;
opcode_size=0; opcode_size=0;
`start_aligning_instruction
/* Emulate MS-DOS print routines */ /* Emulate MS-DOS print routines */
if(CIR[7:0]==8'h21 && register_file.registers[0][15:8]==8'h02)begin if(CIR[7:0]==8'h21 && register_file.registers[0][15:8]==8'h02)begin
$write("%s" ,register_file.registers[2][7:0]); /*TODO:Could trigger erroneously while CIR is not final*/ $write("%s" ,register_file.registers[2][7:0]); /*TODO:Could trigger erroneously while CIR is not final*/
end end
next_state=`PROC_IF_STATE_ENTRY; next_state=`PROC_IF_STATE_ENTRY;
`normal_instruction;
end end
11'b1110_1000_???:begin 11'b1110_1000_xxx:begin
/* CALL - Direct call within segment */ /* CALL - Direct call within segment */
/* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/ /* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/
// Microcode instruction // Microcode instruction
instruction_size=3; instruction_size=3;
`start_unaligning_instruction
opcode_size=0; opcode_size=0;
Wbit=1; Wbit=1;
Sbit=1; Sbit=1;
PARAM2=2; //subtract from sp PARAM2=2; //subtract from sp
seq_addr_entry<=`UCODE_CALL_ENTRY; seq_addr_entry=`UCODE_CALL_ENTRY;
end end
11'b1100_0011_???:begin 11'b1100_0011_xxx:begin
/* RET - Return from call within segment */ /* RET - Return from call within segment */
/* | 1 1 0 0 0 0 1 1 | */ /* | 1 1 0 0 0 0 1 1 | */
// Microcode instruction // Microcode instruction
`start_unaligning_instruction
instruction_size=1; instruction_size=1;
opcode_size=0; opcode_size=0;
Wbit=1; Wbit=1;
Sbit=0; Sbit=0;
PARAM1=2; PARAM1=2;
seq_addr_entry<=`UCODE_RET_ENTRY; seq_addr_entry=`UCODE_RET_ENTRY;
end end
11'b1010_101?_???:begin 11'b1010_101x_xxx:begin
/* STOS - Write byte/word to [DI] and increment accordingly */ /* STOS - Write byte/word to [DI] and increment accordingly */
/* | 1 0 1 0 1 0 1 W | */ /* | 1 0 1 0 1 0 1 W | */
`start_unaligning_instruction
opcode_size=0; opcode_size=0;
instruction_size=1; instruction_size=1;
Wbit=CIR[8:8]; Wbit=CIR[8:8];
Sbit=0; Sbit=0;
RM=3'b101; RM=101;
seq_addr_entry<=`UCODE_STOS_ENTRY; seq_addr_entry=`UCODE_STOS_ENTRY;
PARAM2=(Wbit==1)?2:1; PARAM2=(Wbit==1)?2:1;
end end
11'b0101_0???_???:begin 11'b0101_0xxx_xxx:begin
/* PUSH - SP-=2; [SP]=REG */ /* PUSH - SP-=2; [SP]=REG */
/* | 0 1 0 1 0 REG | */ /* | 0 1 0 1 0 REG | */
`start_unaligning_instruction
opcode_size=0; opcode_size=0;
instruction_size=1; instruction_size=1;
Wbit=1; Wbit=1;
Sbit=0; Sbit=0;
PARAM2=2; PARAM2=2;
reg_read_port2_addr={1'b1,CIR[10:8]}; reg_read_port2_addr={1'b1,CIR[10:8]};
seq_addr_entry<=`UCODE_PUSH_ENTRY; seq_addr_entry=`UCODE_PUSH_ENTRY;
end end
11'b1111_011?_000:begin 11'b1111_011x_000:begin
/* TEST - Bitwise AND affecting only flags */ /* 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 */ /* 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; opcode_size=1;
@ -489,16 +488,18 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
IN_MOD={1'b0,CIR[7:6]}; IN_MOD={1'b0,CIR[7:6]};
RM={CIR[2:0]}; RM={CIR[2:0]};
if(Wbit==1)begin if(Wbit==1)begin
`start_aligning_instruction
instruction_size=4; instruction_size=4;
next_state=`PROC_DE_LOAD_16_PARAM; next_state=`PROC_DE_LOAD_16_PARAM;
end else begin end else begin
instruction_size=3; instruction_size=3;
`start_unaligning_instruction
next_state=`PROC_DE_LOAD_8_PARAM; next_state=`PROC_DE_LOAD_8_PARAM;
end end
in_alu1_sel1=2'b00; /* PARAM1 */ in_alu1_sel1=2'b00; /* PARAM1 */
ALU_1OP=`ALU_OP_AND; ALU_1OP=`ALU_OP_AND;
case(IN_MOD) case(IN_MOD)
3'b011:begin 2'b11:begin
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
end end
@ -507,29 +508,30 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end end
endcase endcase
OUT_MOD=3'b100;/*NULL*/ OUT_MOD=3'b100;/*NULL*/
`normal_instruction;
end end
11'b0101_1???_???:begin 11'b0101_1xxx_xxx:begin
/* POP - REG=[SP]; SP+=2 */ /* POP - REG=[SP]; SP+=2 */
/* | 0 1 0 1 1 REG | */ /* | 0 1 0 1 1 REG | */
`start_unaligning_instruction
opcode_size=0; opcode_size=0;
instruction_size=1; instruction_size=1;
Wbit=1; Wbit=1;
Sbit=0; Sbit=0;
PARAM1=2; PARAM1=2;
reg_write_addr={1'b1,CIR[10:8]}; reg_write_addr={1'b1,CIR[10:8]};
seq_addr_entry<=`UCODE_POP_ENTRY; seq_addr_entry=`UCODE_POP_ENTRY;
end end
11'b1111_1111_100:begin 11'b1111_1111_100:begin
/* JMP - Unconditional indirect within segment jump */ /* JMP - Unconditional indirect within segment jump */
/* 1 1 1 1 1 1 1 1 | MOD 1 0 0 R/M | < DISP-LO > | < DISP-HI > */ /* 1 1 1 1 1 1 1 1 | MOD 1 0 0 R/M | < DISP-LO > | < DISP-HI > */
`start_aligning_instruction
opcode_size=1; opcode_size=1;
instruction_size=2; instruction_size=2;
Wbit=1; Wbit=1;
IN_MOD={1'b0,CIR[7:6]}; IN_MOD={1'b0,CIR[7:6]};
RM=CIR[2:0]; RM=CIR[2:0];
in_alu1_sel1=2'b11; in_alu1_sel1=2'b11;
if (IN_MOD==3'b011)begin if (IN_MOD==2'b11)begin
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
@ -539,9 +541,8 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end end
ALU_1OP=`ALU_OP_ADD; ALU_1OP=`ALU_OP_ADD;
OUT_MOD=3'b101; OUT_MOD=3'b101;
`normal_instruction;
end end
11'b1100_011?_000:begin 11'b1100_011x_000:begin
/* MOV - Move immediate to register/memory */ /* 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 */ /* 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]; Wbit=CIR[8:8];
@ -550,16 +551,18 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
in_alu1_sel2=2'b11; in_alu1_sel2=2'b11;
if(Wbit==1)begin if(Wbit==1)begin
instruction_size=4; instruction_size=4;
`start_aligning_instruction;
next_state=`PROC_DE_LOAD_16_PARAM; next_state=`PROC_DE_LOAD_16_PARAM;
end else begin end else begin
instruction_size=3; instruction_size=3;
`start_unaligning_instruction;
next_state=`PROC_DE_LOAD_8_PARAM; next_state=`PROC_DE_LOAD_8_PARAM;
end end
OUT_MOD={1'b0,CIR[7:6]}; OUT_MOD={1'b0,CIR[7:6]};
IN_MOD=3'b011; IN_MOD=3'b011;
RM=CIR[2:0]; RM=CIR[2:0];
`normal_instruction;
end end
default:begin default:begin
`invalid_instruction `invalid_instruction
@ -569,7 +572,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/*Microcode output*/ /*Microcode output*/
//Sbit, Wbit, opcode_size and the others are still latched //Sbit, Wbit, opcode_size and the others are still latched
//from when we ordered the switch to microcode //from when we ordered the switch to microcode
seq_addr_entry <= ucode_data[`UCODE_ADDR_BITS-1:0]; seq_addr_entry=ucode_data[5:0];
case(ucode_data[7:6]) case(ucode_data[7:6])
2'b00: next_state=`PROC_EX_STATE_ENTRY; 2'b00: next_state=`PROC_EX_STATE_ENTRY;
2'b01: next_state=`PROC_DE_LOAD_16_PARAM; 2'b01: next_state=`PROC_DE_LOAD_16_PARAM;
@ -591,7 +594,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
3'b100: ALU_1OP=`ALU_OP_XOR; 3'b100: ALU_1OP=`ALU_OP_XOR;
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B; 3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE; 3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
default: begin end
endcase endcase
if(ucode_data[33:33]==0) if(ucode_data[33:33]==0)
reg_read_port1_addr=ucode_data[25:22]; reg_read_port1_addr=ucode_data[25:22];
@ -602,7 +604,5 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
Wbit=ucode_data[36:36]; Wbit=ucode_data[36:36];
end end
end end
`undef invalid_instruction
endmodule endmodule
// verilator lint_on BLKSEQ

View File

@ -60,5 +60,3 @@
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2 6'b110010 `define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2 6'b110010
`define PROC_NEXT_MICROCODE 6'b111000 `define PROC_NEXT_MICROCODE 6'b111000
`define PROC_RESET 6'b111100

View File

@ -40,7 +40,7 @@ assign external_data_bus=read?data_bus_output_register:16'hz;
reg [`PROC_STATE_BITS-1:0] state; reg [`PROC_STATE_BITS-1:0] state;
/*############ Decoder ########################################################## */ /*############ Decoder ########################################################## */
wire Wbit, Sbit, opcode_size; wire Wbit, Sbit, unaligning_instruction,opcode_size;
wire [`PROC_STATE_BITS-1:0] next_state; wire [`PROC_STATE_BITS-1:0] next_state;
wire [2:0]RM; wire [2:0]RM;
wire [15:0]DE_PARAM1;// Input param1 form decoder to alu wire [15:0]DE_PARAM1;// Input param1 form decoder to alu
@ -48,7 +48,7 @@ wire [15:0]DE_PARAM2;
wire DE_ERROR,DE_HALT; wire DE_ERROR,DE_HALT;
wire [3:0]DE_reg_read_port1_addr,DE_reg_write_addr,DE_reg_read_port2_addr; wire [3:0]DE_reg_read_port1_addr,DE_reg_write_addr,DE_reg_read_port2_addr;
wire [11:0]DE_REGISTER_CONTROL; wire [11:0]DE_REGISTER_CONTROL;
wire [2:0]INSTRUCTION_INFO; wire [3:0]INSTRUCTION_INFO;
wire [1:0]DECODER_SIGNALS; wire [1:0]DECODER_SIGNALS;
wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry; wire [`UCODE_ADDR_BITS-1:0] ucode_seq_addr_entry;
@ -79,8 +79,9 @@ decoder decoder(
.instruction_size(DE_instruction_size) .instruction_size(DE_instruction_size)
); );
assign Wbit=INSTRUCTION_INFO[2:2]; assign Wbit=INSTRUCTION_INFO[3:3];
assign Sbit=INSTRUCTION_INFO[1:1]; assign Sbit=INSTRUCTION_INFO[2:2];
assign unaligning_instruction=INSTRUCTION_INFO[1:1];
assign opcode_size=INSTRUCTION_INFO[0:0]; assign opcode_size=INSTRUCTION_INFO[0:0];
assign DE_reg_write_addr=DE_REGISTER_CONTROL[11:8]; assign DE_reg_write_addr=DE_REGISTER_CONTROL[11:8];
@ -98,9 +99,9 @@ reg [15:0] CIR;
reg [15:0] PARAM1; reg [15:0] PARAM1;
reg [15:0] PARAM2; reg [15:0] PARAM2;
// verilator lint_off UNDRIVEN reg [15:0]FLAGS;
reg [15:0] FLAGS;
// verilator lint_on UNDRIVEN reg [15:0] BYTE_WRITE_TEMP_REG;//we read 16bits here if we want to change just 8 and leave the rest
//Architectural Register file //Architectural Register file
reg [3:0] reg_write_addr; reg [3:0] reg_write_addr;
@ -129,13 +130,10 @@ register_file register_file(
); );
reg [15:0] ProgCount; reg [15:0] ProgCount;
wire ProgCount_next_opcode;
// verilator lint_off UNUSEDSIGNAL wire ProgCount_arg;
wire [15:0] ProgCount_next_opcode; assign ProgCount_next_opcode=ProgCount+instruction_size;
wire [15:0] ProgCount_arg; assign ProgCount_arg=ProgCount+opcode_size+1;
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 / Execution units ########################################################## */
// ALU 1 // ALU 1
@ -149,7 +147,7 @@ mux4 #(.WIDTH(16)) MUX16_1A(
/*0*/ PARAM1, /*0*/ PARAM1,
/*1*/ reg_read_port1_data, /*1*/ reg_read_port1_data,
/*2*/ ProgCount[15:0], /*2*/ ProgCount[15:0],
/*3*/ 16'd0, /*0 Constant*/ /*3*/ 16'b0000000000000000, /*0 Constant*/
in_alu1_sel1, in_alu1_sel1,
ALU_1A); ALU_1A);
@ -157,7 +155,7 @@ mux4 #(.WIDTH(16)) MUX16_1B(
/*0*/ PARAM2, /*0*/ PARAM2,
/*1*/ reg_read_port2_data, /*1*/ reg_read_port2_data,
/*2*/ ProgCount[15:0], /*2*/ ProgCount[15:0],
/*3*/ 16'd0, /*0 Constant*/ /*3*/ 16'b0000000000000000, /*0 Constant*/
in_alu1_sel2, in_alu1_sel2,
ALU_1B); ALU_1B);
@ -178,31 +176,29 @@ ALU ALU1(
/*############ Processor state machine ########################################################## */ /*############ Processor state machine ########################################################## */
/*** RESET LOGIC ***/ /*** RESET LOGIC ***/
/* verilator lint_off MULTIDRIVEN */
always @(negedge reset) begin always @(negedge reset) begin
state <= `PROC_HALT_STATE; //TODO: race condition ?? 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
end end
always @(posedge reset) begin
state <= `PROC_RESET;
end
/* verilator lint_on MULTIDRIVEN */
/*** Processor stages ***/ /*** 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 always @(posedge clock) begin
case(state) 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 `PROC_HALT_STATE:begin
end end
`PROC_IF_STATE_ENTRY:begin `PROC_IF_STATE_ENTRY:begin
@ -218,13 +214,13 @@ always @(posedge clock) begin
$display("Fetched instruction at %0x",ProgCount - 0); $display("Fetched instruction at %0x",ProgCount - 0);
end end
`endif `endif
BHE <= 0; BHE = 0;
external_address_bus <= {4'b0,ProgCount}; external_address_bus = ProgCount;
read <= 0; read = 0;
write <= 1; write = 1;
reg_write_we <= 1; reg_write_we=1;
state <= `PROC_IF_WRITE_CIR; state=`PROC_IF_WRITE_CIR;
reg_write_in_sel <= 2'b00; reg_write_in_sel=2'b00;
end end
`PROC_IF_WRITE_CIR:begin `PROC_IF_WRITE_CIR:begin
/*I built the entire decode stage with CIR /*I built the entire decode stage with CIR
@ -232,40 +228,40 @@ always @(posedge clock) begin
if(instruction_size==1)begin if(instruction_size==1)begin
/*Half on CIR half on this address */ /*Half on CIR half on this address */
state <= `PROC_DE_STATE_ENTRY; state=`PROC_DE_STATE_ENTRY;
if(ProgCount[0:0]==1)begin 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 end else begin
CIR <= {CIR[7:0],external_data_bus[7:0]}; CIR = {CIR[7:0],external_data_bus[7:0]};
end end
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
end else begin end else begin
if(ProgCount[0:0]==1)begin if(ProgCount[0:0]==1)begin
/* Half on this address half on the next*/ /* Half on this address half on the next*/
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
CIR[15:8] <= external_data_bus[15:8]; 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 end else begin
/* Both on this address! */ /* Both on this address! */
ProgCount <= ProgCount+2; ProgCount=ProgCount+2;
CIR <= {external_data_bus[7:0],external_data_bus[15:8]}; CIR <= {external_data_bus[7:0],external_data_bus[15:8]};
state <= `PROC_DE_STATE_ENTRY; state=`PROC_DE_STATE_ENTRY;
end end
end end
end end
`PROC_IF_STATE_EXTRA_FETCH_SET:begin `PROC_IF_STATE_EXTRA_FETCH_SET:begin
external_address_bus <= {4'b0,ProgCount}; external_address_bus = ProgCount;
BHE <= 0; BHE=0;
state <= `PROC_IF_STATE_EXTRA_FETCH; state=`PROC_IF_STATE_EXTRA_FETCH;
end end
`PROC_IF_STATE_EXTRA_FETCH:begin `PROC_IF_STATE_EXTRA_FETCH:begin
CIR[7:0] <= external_data_bus[7:0]; CIR[7:0] <= external_data_bus[7:0];
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
state <= `PROC_DE_STATE_ENTRY; state=`PROC_DE_STATE_ENTRY;
end end
`PROC_DE_STATE_ENTRY:begin `PROC_DE_STATE_ENTRY:begin
external_address_bus <= {4'b0,ProgCount}; external_address_bus = ProgCount;
if(SIMPLE_MICRO==0)begin if(SIMPLE_MICRO==0)begin
/*This flag is set at reset and jump because /*This flag is set at reset and jump because
* at IF we need to know the size of the * at IF we need to know the size of the
@ -274,110 +270,110 @@ always @(posedge clock) begin
* incorrect in both cases. So when it gets * incorrect in both cases. So when it gets
* set reset it only at the start of the next * set reset it only at the start of the next
* 8086 instruction */ * 8086 instruction */
instruction_size_init <= 0; instruction_size_init=0;
/* We cannot set these directly within /* We cannot set these directly within
* microcode so don't overwrite useful values * microcode so don't overwrite useful values
* each time the next microcode is executed. * each time the next microcode is executed.
* Note this still allows to set initial values * Note this still allows to set initial values
* at the start of the microcode */ * at the start of the microcode */
PARAM1 <= DE_PARAM1; PARAM1=DE_PARAM1;
PARAM2 <= DE_PARAM2; PARAM2=DE_PARAM2;
end end
ERROR <= DE_ERROR; ERROR=DE_ERROR;
HALT <= DE_HALT; HALT=DE_HALT;
reg_read_port1_addr <= DE_reg_read_port1_addr; reg_read_port1_addr=DE_reg_read_port1_addr;
reg_read_port2_addr <= DE_reg_read_port2_addr; reg_read_port2_addr=DE_reg_read_port2_addr;
reg_write_addr <= DE_reg_write_addr; reg_write_addr=DE_reg_write_addr;
if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin if ( (ucode_seq_addr==`UCODE_NO_INSTRUCTION) && (ucode_seq_addr_entry!=`UCODE_NO_INSTRUCTION) )begin
/*switch to microcode decoding*/ /*switch to microcode decoding*/
ucode_seq_addr <= ucode_seq_addr_entry; ucode_seq_addr=ucode_seq_addr_entry;
SIMPLE_MICRO <= 1; SIMPLE_MICRO=1;
/*keep state the same and rerun decode this time with all the data from the microcode rom*/ /*keep state the same and rerun decode this time with all the data from the microcode rom*/
end else begin end else begin
state <= next_state; state=next_state;
end end
end end
`PROC_DE_LOAD_REG_TO_PARAM:begin `PROC_DE_LOAD_REG_TO_PARAM:begin
PARAM2<=reg_read_port2_data; PARAM2=reg_read_port2_data;
case(IN_MOD) case(IN_MOD)
3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state <= `PROC_EX_STATE_ENTRY; default: state=`PROC_EX_STATE_ENTRY;
endcase endcase
end end
`PROC_DE_LOAD_8_PARAM:begin `PROC_DE_LOAD_8_PARAM:begin
if(opcode_size==0)begin if(opcode_size==0)begin
if({Sbit,Wbit}==2'b11)begin if({Sbit,Wbit}==2'b11)begin
/*signed "16bit" read*/ /*signed "16bit" read*/
PARAM1 <= {{8{CIR[7:7]}},CIR[7:0]}; PARAM1 = {{8{CIR[7:7]}},CIR[7:0]};
end else begin end else begin
PARAM1[7:0] <= CIR[7:0]; PARAM1[7:0] = CIR[7:0];
end end
case(IN_MOD) case(IN_MOD)
3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state <= `PROC_EX_STATE_ENTRY; default: state=`PROC_EX_STATE_ENTRY;
endcase endcase
end else begin end else begin
if(ProgCount[0:0]==1)begin if(ProgCount[0:0]==1)begin
if({Sbit,Wbit}==2'b11)begin if({Sbit,Wbit}==2'b11)begin
/*signed "16bit" read*/ /*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 end else begin
PARAM1[7:0] <= external_data_bus[15:8]; PARAM1[7:0] = external_data_bus[15:8];
end end
end else begin end else begin
if({Sbit,Wbit}==2'b11)begin if({Sbit,Wbit}==2'b11)begin
/*signed "16bit" read*/ /*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 end else begin
PARAM1[7:0] <= external_data_bus[7:0]; PARAM1[7:0] = external_data_bus[7:0];
end end
end end
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
case(IN_MOD) case(IN_MOD)
3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state <= `PROC_EX_STATE_ENTRY; default: state=`PROC_EX_STATE_ENTRY;
endcase endcase
end end
end end
`PROC_DE_LOAD_16_PARAM:begin `PROC_DE_LOAD_16_PARAM:begin
if(opcode_size==0)begin if(opcode_size==0)begin
PARAM1[7:0] <= CIR[7:0]; PARAM1[7:0] = CIR[7:0];
if(ProgCount[0:0]==1)begin 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 end else begin
PARAM1[15:8] <= external_data_bus[7:0]; PARAM1[15:8] = external_data_bus[7:0];
end end
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
case(IN_MOD) case(IN_MOD)
3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state <= `PROC_EX_STATE_ENTRY; default: state=`PROC_EX_STATE_ENTRY;
endcase endcase
end else begin end else begin
if(ProgCount[0:0]==1)begin if(ProgCount[0:0]==1)begin
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
PARAM1[7:0] <= external_data_bus[15:8]; PARAM1[7:0] = external_data_bus[15:8];
state <= `PROC_DE_LOAD_16_EXTRA_FETCH_SET; state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET;
end else begin end else begin
PARAM1 <= external_data_bus; PARAM1 = external_data_bus;
ProgCount <= ProgCount+2; ProgCount=ProgCount+2;
case(IN_MOD) case(IN_MOD)
3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state <= `PROC_EX_STATE_ENTRY; default: state=`PROC_EX_STATE_ENTRY;
endcase endcase
end end
end end
end end
`PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin `PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin
external_address_bus <= {4'b0,ProgCount}; external_address_bus = ProgCount;
state <= `PROC_DE_LOAD_16_EXTRA_FETCH; state=`PROC_DE_LOAD_16_EXTRA_FETCH;
end end
`PROC_DE_LOAD_16_EXTRA_FETCH:begin `PROC_DE_LOAD_16_EXTRA_FETCH:begin
ProgCount <= ProgCount+1; ProgCount=ProgCount+1;
PARAM1[15:8] <= external_data_bus[7:0]; PARAM1[15:8] = external_data_bus[7:0];
case(IN_MOD) case(IN_MOD)
3'b000,3'b001,3'b010: state <= `PROC_MEMIO_READ; 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state <= `PROC_EX_STATE_ENTRY; default: state=`PROC_EX_STATE_ENTRY;
endcase endcase
end end
`PROC_MEMIO_READ:begin `PROC_MEMIO_READ:begin
@ -405,13 +401,13 @@ always @(posedge clock) begin
end end
3'b100:begin 3'b100:begin
/*[SI]*/ /*[SI]*/
reg_read_port1_addr <= 4'b1110; reg_read_port1_addr=4'b1110;
state <= `PROC_MEMIO_READ_SETADDR; state=`PROC_MEMIO_READ_SETADDR;
end end
3'b101:begin 3'b101:begin
/*[DI]*/ /*[DI]*/
reg_read_port1_addr <= 4'b1111; reg_read_port1_addr=4'b1111;
state <= `PROC_MEMIO_READ_SETADDR; state=`PROC_MEMIO_READ_SETADDR;
end end
3'b110:begin 3'b110:begin
/*d16 */ /*d16 */
@ -419,8 +415,8 @@ always @(posedge clock) begin
end end
3'b111:begin 3'b111:begin
/*[BX]*/ /*[BX]*/
reg_read_port1_addr <= 4'b1011; reg_read_port1_addr=4'b1011;
state <= `PROC_MEMIO_READ_SETADDR; state=`PROC_MEMIO_READ_SETADDR;
end end
endcase endcase
if(IN_MOD!=3'b000)begin if(IN_MOD!=3'b000)begin
@ -429,8 +425,8 @@ always @(posedge clock) begin
end end
end end
3'b110:begin /* SP Indirect read*/ 3'b110:begin /* SP Indirect read*/
reg_read_port1_addr <= 4'b1100; reg_read_port1_addr=4'b1100;
state <= `PROC_MEMIO_READ_SETADDR; state=`PROC_MEMIO_READ_SETADDR;
end end
default:begin default:begin
`invalid_instruction `invalid_instruction
@ -438,32 +434,32 @@ always @(posedge clock) begin
endcase endcase
end end
`PROC_MEMIO_READ_SETADDR:begin `PROC_MEMIO_READ_SETADDR:begin
external_address_bus <= {4'b0,reg_read_port1_data[15:0]}; 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; state=reg_read_port1_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA;
end end
`PROC_MEMIO_GET_ALIGNED_DATA:begin `PROC_MEMIO_GET_ALIGNED_DATA:begin
PARAM2 <= (Wbit==1)? external_data_bus : {8'b0,external_data_bus[7:0]} ; PARAM2=(Wbit==1)? external_data_bus : {8'b00000000,external_data_bus[7:0]} ;
state <= `PROC_EX_STATE_ENTRY; state=`PROC_EX_STATE_ENTRY;
end end
`PROC_MEMIO_GET_UNALIGNED_DATA:begin `PROC_MEMIO_GET_UNALIGNED_DATA:begin
PARAM2 <= {8'b0,external_data_bus[15:8]}; PARAM2={8'b00000000,external_data_bus[15:8]};
if(Wbit==1) begin if(Wbit==1) begin
state <= `PROC_MEMIO_GET_SECOND_BYTE; state=`PROC_MEMIO_GET_SECOND_BYTE;
end else begin end else begin
state <= `PROC_EX_STATE_ENTRY; state=`PROC_EX_STATE_ENTRY;
end end
end end
`PROC_MEMIO_GET_SECOND_BYTE:begin `PROC_MEMIO_GET_SECOND_BYTE:begin
external_address_bus <= external_address_bus+1; external_address_bus=external_address_bus+1;
state <= `PROC_MEMIO_GET_SECOND_BYTE1; state=`PROC_MEMIO_GET_SECOND_BYTE1;
end end
`PROC_MEMIO_GET_SECOND_BYTE1:begin `PROC_MEMIO_GET_SECOND_BYTE1:begin
PARAM2[15:8] <= external_data_bus[7:0]; PARAM2[15:8]=external_data_bus[7:0];
state <= `PROC_EX_STATE_ENTRY; state=`PROC_EX_STATE_ENTRY;
end end
`PROC_EX_STATE_ENTRY:begin `PROC_EX_STATE_ENTRY:begin
external_address_bus <= {4'b0,ProgCount}; external_address_bus = ProgCount;
FLAGS[7:0] <= ALU_1FLAGS[7:0]; FLAGS[7:0] = ALU_1FLAGS[7:0];
case(OUT_MOD) case(OUT_MOD)
3'b000, 3'b000,
3'b001, 3'b001,
@ -487,13 +483,13 @@ always @(posedge clock) begin
end end
3'b100:begin 3'b100:begin
/*[SI]*/ /*[SI]*/
reg_read_port1_addr <= 4'b1110; reg_read_port1_addr=4'b1110;
state <= `PROC_MEMIO_WRITE; state=`PROC_MEMIO_WRITE;
end end
3'b101:begin 3'b101:begin
/*[DI]*/ /*[DI]*/
reg_read_port1_addr <= 4'b1111; reg_read_port1_addr=4'b1111;
state <= `PROC_MEMIO_WRITE; state=`PROC_MEMIO_WRITE;
end end
3'b110:begin 3'b110:begin
/*d16 */ /*d16 */
@ -501,35 +497,35 @@ always @(posedge clock) begin
end end
3'b111:begin 3'b111:begin
/*[BX]*/ /*[BX]*/
reg_read_port1_addr <= 4'b1011; reg_read_port1_addr=4'b1011;
state <= `PROC_MEMIO_WRITE; state=`PROC_MEMIO_WRITE;
end end
endcase endcase
end end
3'b011:begin 3'b011:begin
reg_write_we <= 0; reg_write_we=0;
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
state <= `PROC_IF_STATE_ENTRY; state=`PROC_IF_STATE_ENTRY;
else else
state <= `PROC_NEXT_MICROCODE; state=`PROC_NEXT_MICROCODE;
end end
3'b100:begin /*No output*/ 3'b100:begin /*No output*/
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
state <= `PROC_IF_STATE_ENTRY; state=`PROC_IF_STATE_ENTRY;
else else
state <= `PROC_NEXT_MICROCODE; state=`PROC_NEXT_MICROCODE;
end end
3'b101:begin /* Program Counter*/ 3'b101:begin /* Program Counter*/
ProgCount <= ALU_1O[15:0]; ProgCount={5'b0000,ALU_1O[15:0]};
instruction_size_init <= 1; instruction_size_init=1;
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
state <= `PROC_IF_STATE_ENTRY; state=`PROC_IF_STATE_ENTRY;
else else
state <= `PROC_NEXT_MICROCODE; state=`PROC_NEXT_MICROCODE;
end end
3'b110:begin /* SP Indirect write*/ 3'b110:begin /* SP Indirect write*/
reg_read_port1_addr <= 4'b1100; reg_read_port1_addr=4'b1100;
state <= `PROC_MEMIO_WRITE; state=`PROC_MEMIO_WRITE;
end end
default:begin default:begin
`invalid_instruction `invalid_instruction
@ -541,66 +537,65 @@ always @(posedge clock) begin
`ifdef DEBUG_MEMORY_WRITES `ifdef DEBUG_MEMORY_WRITES
$display("Writing at %04x , %04x",reg_read_port1_data,ALU_1O); $display("Writing at %04x , %04x",reg_read_port1_data,ALU_1O);
`endif `endif
external_address_bus <= {4'b0,reg_read_port1_data[15:0]}; 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) ; 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 end
`PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA:begin `PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA:begin
read <= 1; read=1;
BHE <= 0; BHE=0;
data_bus_output_register <= {ALU_1O[7:0],ALU_1O[15:8]}; data_bus_output_register={ALU_1O[7:0],ALU_1O[15:8]};
state <= `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT; state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT;
end end
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT:begin `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT:begin
write <= 0; write=0;
state <= `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2; state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2;
end end
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2:begin `PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2:begin
write <= 1; write=1;
external_address_bus <= external_address_bus+1; external_address_bus=external_address_bus+1;
BHE <= 1; BHE=1;
state <= `PROC_MEMIO_WRITE_EXIT; state=`PROC_MEMIO_WRITE_EXIT;
end end
`PROC_MEMIO_PUT_ALIGNED_16BIT_DATA:begin `PROC_MEMIO_PUT_ALIGNED_16BIT_DATA:begin
read <= 1; read=1;
data_bus_output_register <= {ALU_1O[15:8],ALU_1O[7:0]}; data_bus_output_register={ALU_1O[15:8],ALU_1O[7:0]};
state <= `PROC_MEMIO_WRITE_EXIT; state=`PROC_MEMIO_WRITE_EXIT;
end end
`PROC_MEMIO_PUT_BYTE:begin `PROC_MEMIO_PUT_BYTE:begin
read <= 1; read=1;
state <= `PROC_MEMIO_WRITE_EXIT; state=`PROC_MEMIO_WRITE_EXIT;
if(reg_read_port1_data[0:0]==0) begin if(reg_read_port1_data[0:0]==0) begin
BHE <= 1; BHE=1;
data_bus_output_register <= {8'b0,ALU_1O[7:0]}; data_bus_output_register={8'b0,ALU_1O[7:0]};
end else begin 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
end end
`PROC_MEMIO_WRITE_EXIT:begin `PROC_MEMIO_WRITE_EXIT:begin
write <= 0; write=0;
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
state <= `PROC_IF_STATE_ENTRY; state=`PROC_IF_STATE_ENTRY;
else else
state <= `PROC_NEXT_MICROCODE; state=`PROC_NEXT_MICROCODE;
end end
`PROC_NEXT_MICROCODE:begin `PROC_NEXT_MICROCODE:begin
read <= 0; read=0;
write <= 1; // maybe we are coming from MEMIO_WRITE write=1; // maybe we are coming from MEMIO_WRITE
BHE <= 0; BHE=0;
ucode_seq_addr <= ucode_seq_addr_entry; /*Reused for next address*/ ucode_seq_addr=ucode_seq_addr_entry; /*Reused for next address*/
if( ucode_seq_addr_entry == `UCODE_NO_INSTRUCTION )begin if( ucode_seq_addr == `UCODE_NO_INSTRUCTION )begin
/*Finished microcode*/ /*Finished microcode*/
SIMPLE_MICRO <= 0; SIMPLE_MICRO=0;
state <= `PROC_IF_STATE_ENTRY; state=`PROC_IF_STATE_ENTRY;
end else begin end else begin
state <= `PROC_DE_STATE_ENTRY; state=`PROC_DE_STATE_ENTRY;
end end
reg_write_we <= 1; reg_write_we=1;
end end
default:begin default:begin
end end
endcase endcase
end end
`undef invalid_instruction
endmodule endmodule

View File

@ -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[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] : assign read_port1_data[7:0] = ( read_port1_addr[3:3] ? registers[read_port1_addr[2: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] ) ); ( 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]} ) );
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[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] : assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr[2: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] ) ); ( 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]} ) );
`ifdef DEBUG_REG_WRITES `ifdef DEBUG_REG_WRITES
string debug_name; string debug_name;
@ -50,15 +50,15 @@ assign write_Wbit=write_port1_addr[3:3];
always @(negedge write_port1_we) begin always @(negedge write_port1_we) begin
if(write_Wbit==1)begin if(write_Wbit==1)begin
/* Word : AX,CX,DX,BX,SP,BP,SI,DI */ /* 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 end else begin
/* Byte : AL,CL,DL,BL,AX,CX,DX,BX */ /* Byte : AL,CL,DL,BL,AX,CX,DX,BX */
if(write_port1_addr[2:2]==1)begin if(write_port1_addr[2:2]==1)begin
/* Byte */ /* Byte */
registers[ {1'b0,write_port1_addr[1:0]} ][15:8] <= write_port1_data[7:0]; registers[write_port1_addr[1:0]][15:8]=write_port1_data[7:0];
end else begin end else begin
/* Byte */ /* Byte */
registers[ {1'b0,write_port1_addr[1:0]} ][7:0] <= write_port1_data[7:0]; registers[write_port1_addr[1:0]][7:0]=write_port1_data[7:0];
end end
end end

View File

@ -46,12 +46,10 @@ initial begin
$dumpfile(waveform_name); $dumpfile(waveform_name);
$dumpvars(0,p,u1); $dumpvars(0,p,u1);
end end
reset = 0;
clk_enable = 1; clk_enable = 1;
reset = 1; #($random%500)
#(`CPU_SPEED*2)
reset = 0;
#($random%1000)
#(`CPU_SPEED) #(`CPU_SPEED)
reset = 1; reset = 1;
end end
@ -78,8 +76,6 @@ end
always @(posedge clock)begin always @(posedge clock)begin
if(reset==1) if(reset==1)
cycles=cycles+1; cycles=cycles+1;
else
cycles=0;
end end
endmodule endmodule

View File

@ -17,14 +17,14 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
`define UCODE_SIZE 12 `define UCODE_ADDR_BITS 5
`define UCODE_DATA_BITS 38 `define UCODE_DATA_BITS 38
`define UCODE_ADDR_BITS $clog2(`UCODE_SIZE) `define UCODE_SIZE 12
/* DEFINE ADDRESSES IN THE MICROCODE */ /* DEFINE ADDRESSES IN THE MICROCODE */
`define UCODE_NO_INSTRUCTION 4'b0000 `define UCODE_NO_INSTRUCTION 5'b00000
`define UCODE_CALL_ENTRY 4'b0001 `define UCODE_CALL_ENTRY 5'b00001
`define UCODE_RET_ENTRY 4'b0100 `define UCODE_RET_ENTRY 5'b00100
`define UCODE_STOS_ENTRY 4'b0110 `define UCODE_STOS_ENTRY 5'b00110
`define UCODE_PUSH_ENTRY 4'b1000 `define UCODE_PUSH_ENTRY 5'b01000
`define UCODE_POP_ENTRY 4'b1010 `define UCODE_POP_ENTRY 5'b01010