Overhauled cpu frontend. Made memory byte addressable (necessary), cleaned up state machine and fixed small bug with MOV
This commit is contained in:
parent
70a9ce6368
commit
f60084344e
@ -73,3 +73,21 @@ Flag register:
|
|||||||
* D - Direction flag : 1: string instructions decrement 0: they increment
|
* D - Direction flag : 1: string instructions decrement 0: they increment
|
||||||
|
|
||||||
* O - Overflow flag : set on arithmetic overflow
|
* O - Overflow flag : set on arithmetic overflow
|
||||||
|
|
||||||
|
### Memory addressing
|
||||||
|
Memory is split into two 8bit banks and can be addresses separately with the A0 line and BHE pin
|
||||||
|
|
||||||
|
| BHE | A0 | OPERATION |
|
||||||
|
|:-----:|:----:|-------------------------------|
|
||||||
|
| 0 | 0 |Both bytes addresses |
|
||||||
|
| 0 | 1 |Only higher 15:8 bits addressed|
|
||||||
|
| 1 | 0 |Only lower 7:0 bits addressed |
|
||||||
|
| 1 | 1 |No bits are addressed |
|
||||||
|
|
||||||
|
Essentially address bits 19:1 address a 16bit memory while bits A0 and BHE select what byte(s) will be read or written
|
||||||
|
|
||||||
|
|A1,A2| HBE=0 A0=1 | HBE=1 A0=0 |
|
||||||
|
|-----|:----------:|:----------:|
|
||||||
|
| 0,0 | B1 | B0 |
|
||||||
|
| 0,1 | B3 | B2 |
|
||||||
|
| 1,0 | B5 | B4 |
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
start:
|
start:
|
||||||
|
MOV SP,#STACK
|
||||||
MOV AX,#0x0000
|
MOV AX,#0x0000
|
||||||
MOV CX,#0x0000
|
MOV CX,#0x0000
|
||||||
MOV BX,#0x0000
|
MOV BX,#0x0000
|
||||||
ADD AX,#0xDEAD
|
CALL TEST_
|
||||||
ADD CX,#0xBEEF
|
ADD CX,#0xBEEF
|
||||||
ADD CX,#0x4111
|
ADD CX,#0x4111
|
||||||
mov AX,#0x00FF
|
mov AX,#0x00FF
|
||||||
@ -30,3 +31,9 @@ mov ah,#2
|
|||||||
mov dl,#'0
|
mov dl,#'0
|
||||||
int #0x21
|
int #0x21
|
||||||
hlt
|
hlt
|
||||||
|
TEST_:
|
||||||
|
ADD AX,#0xDEAD
|
||||||
|
RET
|
||||||
|
|
||||||
|
.BLKB 10
|
||||||
|
STACK:
|
||||||
|
@ -43,12 +43,13 @@ assign DATA=ucode[ADDR];
|
|||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module decoder(
|
module decoder(
|
||||||
input wire [15:0] CIR,input wire [15:0] FLAGS, output wire [4: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
|
||||||
,output reg [2:0]ALU_1OP
|
,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 [`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
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [3:0]reg_read_port1_addr;
|
reg [3:0]reg_read_port1_addr;
|
||||||
@ -57,8 +58,8 @@ 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,unaligning,opcode_size,has_operands;
|
reg Wbit,Sbit,unaligning,opcode_size;
|
||||||
assign INSTRUCTION_INFO={Wbit,Sbit,unaligning,opcode_size,has_operands};
|
assign INSTRUCTION_INFO={Wbit,Sbit,unaligning,opcode_size};
|
||||||
|
|
||||||
reg ERROR, HALT;
|
reg ERROR, HALT;
|
||||||
assign DECODER_SIGNALS={ERROR,HALT};
|
assign DECODER_SIGNALS={ERROR,HALT};
|
||||||
@ -87,12 +88,14 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) 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;
|
||||||
has_operands=1;
|
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
if(Wbit)
|
if(Wbit)begin
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
else
|
instruction_size=3;
|
||||||
|
end else begin
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
|
instruction_size=2;
|
||||||
|
end
|
||||||
IN_MOD=2'b11;
|
IN_MOD=2'b11;
|
||||||
in_alu1_sel1=2'b00;
|
in_alu1_sel1=2'b00;
|
||||||
in_alu1_sel2=2'b01;
|
in_alu1_sel2=2'b01;
|
||||||
@ -112,7 +115,6 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* SUB - Subtract immediate word/byte from register/memory */
|
/* SUB - Subtract immediate word/byte from register/memory */
|
||||||
/* 1 0 0 0 0 0 S W | MOD 1 0 1 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */
|
/* 1 0 0 0 0 0 S W | MOD 1 0 1 R/M | < DISP LO > | < DISP HI > | DATA | DATA if W | */
|
||||||
opcode_size=1;
|
opcode_size=1;
|
||||||
has_operands=1;
|
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
Sbit=CIR[9:9];
|
Sbit=CIR[9:9];
|
||||||
IN_MOD=CIR[7:6];
|
IN_MOD=CIR[7:6];
|
||||||
@ -130,10 +132,12 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
2'b00,2'b11:begin
|
2'b00,2'b11:begin
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
next_state=`PROC_DE_LOAD_8_PARAM;
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
|
instruction_size=3;
|
||||||
end
|
end
|
||||||
2'b01:begin
|
2'b01:begin
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
next_state=`PROC_DE_LOAD_16_PARAM;
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
|
instruction_size=4;
|
||||||
end
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
@ -152,16 +156,17 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) 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;
|
||||||
has_operands=1;
|
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
Sbit=CIR[9:9];
|
Sbit=CIR[9:9];
|
||||||
IN_MOD=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;
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
end
|
end
|
||||||
2'b01:begin
|
2'b01:begin
|
||||||
|
instruction_size=4;
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
end
|
end
|
||||||
2'b10:begin
|
2'b10:begin
|
||||||
@ -187,8 +192,8 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) 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
|
`start_aligning_instruction
|
||||||
has_operands=1;
|
|
||||||
Wbit=CIR[11:11]; /* IS 0 */
|
Wbit=CIR[11:11]; /* IS 0 */
|
||||||
|
instruction_size=2;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
IN_MOD=2'b11;
|
IN_MOD=2'b11;
|
||||||
in_alu1_sel1=2'b00;
|
in_alu1_sel1=2'b00;
|
||||||
@ -203,8 +208,8 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
11'b1011_1xxx_xxx : begin
|
11'b1011_1xxx_xxx : begin
|
||||||
/*MOV - Move Immediate word to register*/
|
/*MOV - Move Immediate word to register*/
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
has_operands=1;
|
|
||||||
Wbit=CIR[11:11]; /*IS 1 */
|
Wbit=CIR[11:11]; /*IS 1 */
|
||||||
|
instruction_size=3;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
IN_MOD=2'b11;
|
IN_MOD=2'b11;
|
||||||
in_alu1_sel1=2'b00;
|
in_alu1_sel1=2'b00;
|
||||||
@ -219,16 +224,16 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
11'b1000_10xx_xxx : 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 > |*/
|
||||||
has_operands=0;
|
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
opcode_size=1;
|
opcode_size=1;
|
||||||
IN_MOD=CIR[7:6];
|
instruction_size=2;
|
||||||
RM=CIR[2:0];
|
RM=CIR[2:0];
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
in_alu1_sel1=2'b00;
|
in_alu1_sel1=2'b00;
|
||||||
PARAM1=0;
|
PARAM1=0;
|
||||||
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]};
|
||||||
if(IN_MOD==2'b11)begin
|
if(IN_MOD==2'b11)begin
|
||||||
/*Reg to Reg*/
|
/*Reg to Reg*/
|
||||||
in_alu1_sel2=2'b01;
|
in_alu1_sel2=2'b01;
|
||||||
@ -243,16 +248,16 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
reg_write_addr={Wbit,CIR[5:3]};
|
reg_write_addr={Wbit,CIR[5:3]};
|
||||||
end else begin
|
end else begin
|
||||||
/* Reg to Mem/Reg */
|
/* Reg to Mem/Reg */
|
||||||
|
IN_MOD=3'b011;
|
||||||
|
OUT_MOD={1'b0,CIR[7:6]};
|
||||||
if(IN_MOD==2'b11)begin
|
if(IN_MOD==2'b11)begin
|
||||||
/*Reg to Reg*/
|
/*Reg to Reg*/
|
||||||
in_alu1_sel2=2'b01;
|
in_alu1_sel2=2'b01;
|
||||||
OUT_MOD=3'b011;
|
|
||||||
reg_write_addr={Wbit,RM};
|
reg_write_addr={Wbit,RM};
|
||||||
next_state=`PROC_EX_STATE_ENTRY;
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
end else begin
|
end else begin
|
||||||
/*Reg to Mem*/
|
/*Reg to Mem*/
|
||||||
in_alu1_sel2=2'b00;
|
in_alu1_sel2=2'b00;
|
||||||
OUT_MOD={1'b0,IN_MOD};
|
|
||||||
next_state=`PROC_DE_LOAD_REG_TO_PARAM;
|
next_state=`PROC_DE_LOAD_REG_TO_PARAM;
|
||||||
end
|
end
|
||||||
reg_read_port2_addr={Wbit,CIR[5:3]};
|
reg_read_port2_addr={Wbit,CIR[5:3]};
|
||||||
@ -265,7 +270,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* | 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 | */
|
||||||
has_operands=0;
|
instruction_size=1;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
@ -287,7 +292,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* 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> */
|
||||||
has_operands=0;
|
instruction_size=2;
|
||||||
opcode_size=1;
|
opcode_size=1;
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
@ -311,7 +316,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
11'b1111_0100_xxx : 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 | */
|
||||||
has_operands=0;
|
instruction_size=1;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
IN_MOD=2'b11;
|
IN_MOD=2'b11;
|
||||||
@ -326,11 +331,13 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* W flag and my assembler seem to disagree */
|
/* W flag and my assembler seem to disagree */
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
has_operands=1;
|
if(Wbit)begin
|
||||||
if(Wbit)
|
instruction_size=3;
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
else
|
end else begin
|
||||||
|
instruction_size=2;
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
|
end
|
||||||
IN_MOD=2'b11;
|
IN_MOD=2'b11;
|
||||||
in_alu1_sel1=2'b00;
|
in_alu1_sel1=2'b00;
|
||||||
in_alu1_sel2=2'b01;
|
in_alu1_sel2=2'b01;
|
||||||
@ -353,7 +360,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* JNS -Jump on not Sign */
|
/* JNS -Jump on not Sign */
|
||||||
/* 0 1 1 1 1 0 0 1 | IP-INC8 |*/
|
/* 0 1 1 1 1 0 0 1 | IP-INC8 |*/
|
||||||
/* .... */
|
/* .... */
|
||||||
has_operands=1;
|
instruction_size=2;
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
@ -401,8 +408,8 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) 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
|
`start_aligning_instruction
|
||||||
|
instruction_size=2;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
has_operands=1;
|
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
in_alu1_sel1=2'b10;
|
in_alu1_sel1=2'b10;
|
||||||
in_alu1_sel2=2'b00;
|
in_alu1_sel2=2'b00;
|
||||||
@ -414,7 +421,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
11'b1100_1101_xxx: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 |*/
|
||||||
has_operands=1;
|
instruction_size=2;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
`start_aligning_instruction
|
`start_aligning_instruction
|
||||||
/* Emulate MS-DOS print routines */
|
/* Emulate MS-DOS print routines */
|
||||||
@ -428,9 +435,9 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* 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;
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
has_operands=1;
|
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
Sbit=1;
|
Sbit=1;
|
||||||
PARAM2=2; //subtract from sp
|
PARAM2=2; //subtract from sp
|
||||||
@ -442,13 +449,8 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
|
|
||||||
// Microcode instruction
|
// Microcode instruction
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
|
instruction_size=1;
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
/* TODO: This is a hack to prevent IF from
|
|
||||||
* thinking it can retrieve half of the opcode
|
|
||||||
* from CIR and the previous byte on the data
|
|
||||||
* bus. We are jumping so all that data has to
|
|
||||||
* be thrown away */
|
|
||||||
has_operands=1;
|
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
Sbit=0;
|
Sbit=0;
|
||||||
PARAM1=2;
|
PARAM1=2;
|
||||||
@ -459,7 +461,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* | 1 0 1 0 1 0 1 W | */
|
/* | 1 0 1 0 1 0 1 W | */
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
has_operands=0;
|
instruction_size=1;
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
Sbit=0;
|
Sbit=0;
|
||||||
RM=101;
|
RM=101;
|
||||||
@ -471,7 +473,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* | 0 1 0 1 0 REG | */
|
/* | 0 1 0 1 0 REG | */
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
has_operands=0;
|
instruction_size=1;
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
Sbit=0;
|
Sbit=0;
|
||||||
PARAM2=2;
|
PARAM2=2;
|
||||||
@ -482,14 +484,15 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) 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;
|
||||||
has_operands=1;
|
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
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
|
`start_aligning_instruction
|
||||||
|
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;
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
next_state=`PROC_DE_LOAD_8_PARAM;
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
end
|
end
|
||||||
@ -511,7 +514,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* | 0 1 0 1 1 REG | */
|
/* | 0 1 0 1 1 REG | */
|
||||||
`start_unaligning_instruction
|
`start_unaligning_instruction
|
||||||
opcode_size=0;
|
opcode_size=0;
|
||||||
has_operands=0;
|
instruction_size=1;
|
||||||
Wbit=1;
|
Wbit=1;
|
||||||
Sbit=0;
|
Sbit=0;
|
||||||
PARAM1=2;
|
PARAM1=2;
|
||||||
@ -523,7 +526,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* 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
|
`start_aligning_instruction
|
||||||
opcode_size=1;
|
opcode_size=1;
|
||||||
has_operands=0;
|
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];
|
||||||
@ -544,13 +547,14 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
/* 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];
|
||||||
opcode_size=1;
|
opcode_size=1;
|
||||||
has_operands=1;
|
|
||||||
in_alu1_sel1=2'b00;
|
in_alu1_sel1=2'b00;
|
||||||
in_alu1_sel2=2'b11;
|
in_alu1_sel2=2'b11;
|
||||||
if(Wbit==1)begin
|
if(Wbit==1)begin
|
||||||
|
instruction_size=4;
|
||||||
`start_aligning_instruction;
|
`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;
|
||||||
`start_unaligning_instruction;
|
`start_unaligning_instruction;
|
||||||
next_state=`PROC_DE_LOAD_8_PARAM;
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
end
|
end
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
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/>. */
|
||||||
|
|
||||||
module mem(input [19:0] address,inout wire [15:0] data ,input rd,input wr,input cs);
|
module doublemem(input [19:0] address,inout wire [15:0] data ,input rd,input wr,input BHE,input cs);
|
||||||
reg [15:0] memory [0:32768];
|
reg [15:0] memory [0:32768];
|
||||||
initial begin
|
initial begin
|
||||||
string boot_code;
|
string boot_code;
|
||||||
@ -28,10 +28,15 @@ initial begin
|
|||||||
$readmemh(boot_code, memory,0,16383);
|
$readmemh(boot_code, memory,0,16383);
|
||||||
end
|
end
|
||||||
|
|
||||||
assign data = !rd & !cs ? memory[address[15:0]]: 16'hz;
|
assign data[7:0] = !address[0:0] & !rd & !cs ? memory[address[15:1]][15:8] : 16'hz;
|
||||||
|
|
||||||
|
assign data[15:8] = !BHE & !rd & !cs ? memory[address[15:1]][7:0] : 16'hz;
|
||||||
|
|
||||||
always @(negedge wr) begin
|
always @(negedge wr) begin
|
||||||
memory[address[15:0]]=data;
|
if(BHE==0)
|
||||||
|
memory[address[15:1]][7:0]=data[15:8];
|
||||||
|
if(address[0]==0)
|
||||||
|
memory[address[15:1]][15:8]=data[7:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
`define PROC_IF_STATE_EXTRA_FETCH_SET 6'b000011
|
`define PROC_IF_STATE_EXTRA_FETCH_SET 6'b000011
|
||||||
`define PROC_IF_STATE_EXTRA_FETCH 6'b000100
|
`define PROC_IF_STATE_EXTRA_FETCH 6'b000100
|
||||||
|
|
||||||
|
|
||||||
/*DECODE SATE*/
|
/*DECODE SATE*/
|
||||||
`define PROC_DE_STATE_ENTRY 6'b001000
|
`define PROC_DE_STATE_ENTRY 6'b001000
|
||||||
`define PROC_DE_LOAD_16_PARAM 6'b001001
|
`define PROC_DE_LOAD_16_PARAM 6'b001001
|
||||||
@ -44,7 +45,6 @@
|
|||||||
`define PROC_MEMIO_GET_SECOND_BYTE 6'b010100
|
`define PROC_MEMIO_GET_SECOND_BYTE 6'b010100
|
||||||
`define PROC_MEMIO_GET_SECOND_BYTE1 6'b010101
|
`define PROC_MEMIO_GET_SECOND_BYTE1 6'b010101
|
||||||
`define PROC_DE_LOAD_8_PARAM 6'b010110
|
`define PROC_DE_LOAD_8_PARAM 6'b010110
|
||||||
`define PROC_DE_LOAD_8_PARAM_UNALIGNED 6'b010111
|
|
||||||
|
|
||||||
/*EXECUTE STATE*/
|
/*EXECUTE STATE*/
|
||||||
`define PROC_EX_STATE_ENTRY 6'b100000
|
`define PROC_EX_STATE_ENTRY 6'b100000
|
||||||
@ -52,16 +52,11 @@
|
|||||||
/*MEM/IO WRITE*/
|
/*MEM/IO WRITE*/
|
||||||
`define PROC_MEMIO_WRITE 6'b101000
|
`define PROC_MEMIO_WRITE 6'b101000
|
||||||
//`define PROC_MEMIO_WRITE_SETADDR 6'b010101
|
//`define PROC_MEMIO_WRITE_SETADDR 6'b010101
|
||||||
`define PROC_MEMIO_PUT_ALIGNED_DATA 6'b101001
|
`define PROC_MEMIO_PUT_ALIGNED_16BIT_DATA 6'b101001
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_DATA 6'b101010
|
`define PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA 6'b101010
|
||||||
`define PROC_MEMIO_PUT_BYTE 6'b101011
|
`define PROC_MEMIO_PUT_BYTE 6'b101011
|
||||||
`define PROC_MEMIO_PUT_BYTE_STOP_READ 6'b101100
|
|
||||||
`define PROC_MEMIO_WRITE_EXIT 6'b101101
|
`define PROC_MEMIO_WRITE_EXIT 6'b101101
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_FIRST_BYTE 6'b101110
|
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT 6'b101111
|
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT 6'b101111
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT1 6'b110001
|
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2 6'b110010
|
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2 6'b110010
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT3 6'b110011
|
|
||||||
`define PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT4 6'b110100
|
|
||||||
|
|
||||||
`define PROC_NEXT_MICROCODE 6'b111000
|
`define PROC_NEXT_MICROCODE 6'b111000
|
||||||
|
@ -22,7 +22,14 @@
|
|||||||
`include "config.v"
|
`include "config.v"
|
||||||
`include "ucode_header.v"
|
`include "ucode_header.v"
|
||||||
|
|
||||||
module processor ( 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 HALT,output reg ERROR);
|
//HALT: active high
|
||||||
|
//ERROR: active high
|
||||||
|
//IOMEM: 1=IO 0=MEM
|
||||||
|
//write: active low
|
||||||
|
//read: active low
|
||||||
|
//reset: active low
|
||||||
|
|
||||||
|
module processor ( 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, output reg HALT,output reg ERROR);
|
||||||
|
|
||||||
/*if we don't read, output the register to have the bus stable by the write falling edge*/
|
/*if we don't read, output the register to have the bus stable by the write falling edge*/
|
||||||
reg [15:0] data_bus_output_register;
|
reg [15:0] data_bus_output_register;
|
||||||
@ -33,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, unaligning_instruction,opcode_size, has_operands;
|
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
|
||||||
@ -41,26 +48,41 @@ 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 [4: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;
|
||||||
|
|
||||||
reg SIMPLE_MICRO; /* otuput simple decodings (=0) or microcode data (=1) */
|
reg SIMPLE_MICRO; /* otuput simple decodings (=0) or microcode data (=1) */
|
||||||
|
wire [2:0] DE_instruction_size;
|
||||||
|
reg instruction_size_init;
|
||||||
|
wire [2:0] instruction_size;
|
||||||
|
assign instruction_size = instruction_size_init ? 3'b010 : DE_instruction_size;
|
||||||
|
|
||||||
decoder decoder(
|
decoder decoder(
|
||||||
CIR,FLAGS,INSTRUCTION_INFO,DECODER_SIGNALS,next_state
|
.CIR(CIR),
|
||||||
,IN_MOD,RM,DE_PARAM1,DE_PARAM2
|
.FLAGS(FLAGS),
|
||||||
,in_alu1_sel1,in_alu1_sel2,OUT_MOD
|
.INSTRUCTION_INFO(INSTRUCTION_INFO),
|
||||||
,DE_REGISTER_CONTROL
|
.DECODER_SIGNALS(DECODER_SIGNALS),
|
||||||
,ALU_1OP
|
.next_state(next_state),
|
||||||
,ucode_seq_addr_entry,SIMPLE_MICRO,ucode_seq_addr
|
.IN_MOD(IN_MOD),
|
||||||
|
.RM(RM),
|
||||||
|
.PARAM1(DE_PARAM1),
|
||||||
|
.PARAM2(DE_PARAM2),
|
||||||
|
.in_alu1_sel1(in_alu1_sel1),
|
||||||
|
.in_alu1_sel2(in_alu1_sel2),
|
||||||
|
.OUT_MOD(OUT_MOD),
|
||||||
|
.REGISTER_FILE_CONTROL(DE_REGISTER_CONTROL),
|
||||||
|
.ALU_1OP(ALU_1OP),
|
||||||
|
.seq_addr_entry(ucode_seq_addr_entry),
|
||||||
|
.SIMPLE_MICRO(SIMPLE_MICRO),
|
||||||
|
.seq_addr_input(ucode_seq_addr),
|
||||||
|
.instruction_size(DE_instruction_size)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign Wbit=INSTRUCTION_INFO[4:4];
|
assign Wbit=INSTRUCTION_INFO[3:3];
|
||||||
assign Sbit=INSTRUCTION_INFO[3:3];
|
assign Sbit=INSTRUCTION_INFO[2:2];
|
||||||
assign unaligning_instruction=INSTRUCTION_INFO[2:2];
|
assign unaligning_instruction=INSTRUCTION_INFO[1:1];
|
||||||
assign opcode_size=INSTRUCTION_INFO[1:1];
|
assign opcode_size=INSTRUCTION_INFO[0:0];
|
||||||
assign has_operands=INSTRUCTION_INFO[0:0];
|
|
||||||
|
|
||||||
assign DE_reg_write_addr=DE_REGISTER_CONTROL[11:8];
|
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_port1_addr=DE_REGISTER_CONTROL[7:4];
|
||||||
@ -73,13 +95,9 @@ reg [`UCODE_ADDR_BITS-1:0] ucode_seq_addr;
|
|||||||
|
|
||||||
/*############ REGISTERS ########################################################## */
|
/*############ REGISTERS ########################################################## */
|
||||||
|
|
||||||
reg [19:0] ProgCount; //TODO: do i create a lot of adders each place i increment it?
|
|
||||||
reg [15:0] CIR;
|
reg [15:0] CIR;
|
||||||
reg [15:0] PARAM1;
|
reg [15:0] PARAM1;
|
||||||
reg [15:0] PARAM2;
|
reg [15:0] PARAM2;
|
||||||
reg one_byte_instruction;
|
|
||||||
reg unaligned_access;
|
|
||||||
reg we_jumped; /*Only used to signify that a microcoded instruction jumped and we should not update the unaligned_access bit after the end of the instruction*/
|
|
||||||
|
|
||||||
reg [15:0]FLAGS;
|
reg [15:0]FLAGS;
|
||||||
|
|
||||||
@ -101,7 +119,21 @@ mux4 #(.WIDTH(16)) REG_FILE_WRITE_IN_MUX(
|
|||||||
16'hz,
|
16'hz,
|
||||||
reg_write_in_sel,
|
reg_write_in_sel,
|
||||||
reg_write_data);
|
reg_write_data);
|
||||||
register_file register_file(reg_write_addr,reg_write_data,reg_write_we,reg_read_port1_addr,reg_read_port1_data,reg_read_port2_addr,reg_read_port2_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)
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
/*############ ALU / Execution units ########################################################## */
|
/*############ ALU / Execution units ########################################################## */
|
||||||
// ALU 1
|
// ALU 1
|
||||||
@ -114,7 +146,7 @@ reg [2:0] OUT_MOD;
|
|||||||
mux4 #(.WIDTH(16)) MUX16_1A(
|
mux4 #(.WIDTH(16)) MUX16_1A(
|
||||||
/*0*/ PARAM1,
|
/*0*/ PARAM1,
|
||||||
/*1*/ reg_read_port1_data,
|
/*1*/ reg_read_port1_data,
|
||||||
/*2*/ {ProgCount[14:0],unaligned_access^unaligning_instruction},
|
/*2*/ ProgCount[15:0],
|
||||||
/*3*/ 16'b0000000000000000, /*0 Constant*/
|
/*3*/ 16'b0000000000000000, /*0 Constant*/
|
||||||
in_alu1_sel1,
|
in_alu1_sel1,
|
||||||
ALU_1A);
|
ALU_1A);
|
||||||
@ -122,7 +154,7 @@ mux4 #(.WIDTH(16)) MUX16_1A(
|
|||||||
mux4 #(.WIDTH(16)) MUX16_1B(
|
mux4 #(.WIDTH(16)) MUX16_1B(
|
||||||
/*0*/ PARAM2,
|
/*0*/ PARAM2,
|
||||||
/*1*/ reg_read_port2_data,
|
/*1*/ reg_read_port2_data,
|
||||||
/*2*/ {ProgCount[14:0],unaligned_access^unaligning_instruction},
|
/*2*/ ProgCount[15:0],
|
||||||
/*3*/ 16'b0000000000000000, /*0 Constant*/
|
/*3*/ 16'b0000000000000000, /*0 Constant*/
|
||||||
in_alu1_sel2,
|
in_alu1_sel2,
|
||||||
ALU_1B);
|
ALU_1B);
|
||||||
@ -132,7 +164,14 @@ wire [15:0] ALU_1B;
|
|||||||
wire [15:0] ALU_1O;
|
wire [15:0] ALU_1O;
|
||||||
reg [`ALU_OP_BITS-1:0]ALU_1OP;
|
reg [`ALU_OP_BITS-1:0]ALU_1OP;
|
||||||
wire [7:0] ALU_1FLAGS;
|
wire [7:0] ALU_1FLAGS;
|
||||||
ALU ALU1(ALU_1A,ALU_1B,ALU_1O,ALU_1OP,ALU_1FLAGS,Wbit);
|
ALU ALU1(
|
||||||
|
.A(ALU_1A),
|
||||||
|
.B(ALU_1B),
|
||||||
|
.OUT(ALU_1O),
|
||||||
|
.op(ALU_1OP),
|
||||||
|
.FLAGS(ALU_1FLAGS),
|
||||||
|
.Wbit(Wbit)
|
||||||
|
);
|
||||||
|
|
||||||
/*############ Processor state machine ########################################################## */
|
/*############ Processor state machine ########################################################## */
|
||||||
|
|
||||||
@ -145,98 +184,19 @@ always @(negedge reset) begin
|
|||||||
ProgCount=0;//TODO: Reset Vector
|
ProgCount=0;//TODO: Reset Vector
|
||||||
HALT=0;
|
HALT=0;
|
||||||
reg_write_we=1;
|
reg_write_we=1;
|
||||||
unaligned_access=0;
|
IOMEM=0;
|
||||||
@(posedge reset)
|
@(posedge reset)
|
||||||
@(negedge clock);
|
@(negedge clock);
|
||||||
state=`PROC_IF_STATE_ENTRY;
|
state=`PROC_IF_STATE_ENTRY;
|
||||||
one_byte_instruction=0;
|
|
||||||
ERROR=0;
|
ERROR=0;
|
||||||
SIMPLE_MICRO=0;
|
SIMPLE_MICRO=0;
|
||||||
|
instruction_size_init=1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
/*** 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 @(negedge clock) begin
|
|
||||||
case(state)
|
|
||||||
`PROC_IF_WRITE_CIR:begin
|
|
||||||
if(unaligned_access)begin
|
|
||||||
if(one_byte_instruction==1)begin /*TODO: have a read buffer so we can do this even with data reads */
|
|
||||||
CIR <= {CIR[7:0],external_data_bus[15:8]};
|
|
||||||
state=`PROC_DE_STATE_ENTRY;
|
|
||||||
end else begin
|
|
||||||
CIR[15:8] <= external_data_bus[7:0];
|
|
||||||
state=`PROC_IF_STATE_EXTRA_FETCH_SET;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
CIR <= external_data_bus;
|
|
||||||
ProgCount=ProgCount+1;
|
|
||||||
state=`PROC_DE_STATE_ENTRY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
`PROC_IF_STATE_EXTRA_FETCH:begin
|
|
||||||
CIR[7:0] <= external_data_bus[15:8];
|
|
||||||
state=`PROC_DE_STATE_ENTRY;
|
|
||||||
end
|
|
||||||
`PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin
|
|
||||||
external_address_bus = ProgCount;
|
|
||||||
state=`PROC_DE_LOAD_16_EXTRA_FETCH;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_READ_SETADDR:begin
|
|
||||||
external_address_bus = {5'b00000,reg_read_port1_data[15:1]};
|
|
||||||
state=reg_read_port1_data[0:0]?`PROC_MEMIO_GET_UNALIGNED_DATA:`PROC_MEMIO_GET_ALIGNED_DATA;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_PUT_BYTE:begin
|
|
||||||
BYTE_WRITE_TEMP_REG=external_data_bus;
|
|
||||||
state=`PROC_MEMIO_PUT_BYTE_STOP_READ;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_WRITE_EXIT:begin
|
|
||||||
write=0;
|
|
||||||
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
|
||||||
state=`PROC_IF_STATE_ENTRY;
|
|
||||||
else
|
|
||||||
state=`PROC_NEXT_MICROCODE;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_PUT_ALIGNED_DATA:begin
|
|
||||||
read=1;
|
|
||||||
data_bus_output_register={ALU_1O[7:0],ALU_1O[15:8]};
|
|
||||||
state=`PROC_MEMIO_WRITE_EXIT;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_PUT_UNALIGNED_DATA:begin
|
|
||||||
BYTE_WRITE_TEMP_REG=external_data_bus;
|
|
||||||
state=`PROC_MEMIO_PUT_UNALIGNED_FIRST_BYTE;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT:begin
|
|
||||||
write=0;
|
|
||||||
state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2;
|
|
||||||
data_bus_output_register={BYTE_WRITE_TEMP_REG[15:8],ALU_1O[7:0]};
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT3:begin
|
|
||||||
BYTE_WRITE_TEMP_REG=external_data_bus;
|
|
||||||
state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT4;
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_GET_SECOND_BYTE:begin
|
|
||||||
external_address_bus=external_address_bus+1;
|
|
||||||
state=`PROC_MEMIO_GET_SECOND_BYTE1;
|
|
||||||
end
|
|
||||||
`PROC_DE_LOAD_8_PARAM_UNALIGNED:begin
|
|
||||||
if({Sbit,Wbit}==2'b11)begin
|
|
||||||
PARAM1 = {{8{external_data_bus[15:15]}},external_data_bus[15:8]};
|
|
||||||
end else begin
|
|
||||||
PARAM1[7:0] = external_data_bus[15:8];
|
|
||||||
end
|
|
||||||
case(IN_MOD)
|
|
||||||
3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
|
|
||||||
default: state=`PROC_EX_STATE_ENTRY;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
default:begin
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
case(state)
|
case(state)
|
||||||
`PROC_HALT_STATE:begin
|
`PROC_HALT_STATE:begin
|
||||||
@ -247,34 +207,71 @@ always @(posedge clock) begin
|
|||||||
* testbench stop the clock after ERROR gets
|
* testbench stop the clock after ERROR gets
|
||||||
* raised the logic for the rising edge still
|
* raised the logic for the rising edge still
|
||||||
* gets triggered printing this debug message. */
|
* gets triggered printing this debug message. */
|
||||||
if(ERROR!=1)
|
if(ERROR!=1)begin
|
||||||
$display("Fetched instruction at %04x",{ProgCount[18:0],unaligned_access});
|
if(instruction_size==1)
|
||||||
|
$display("Fetched instruction at %0x",ProgCount - 1);
|
||||||
|
else
|
||||||
|
$display("Fetched instruction at %0x",ProgCount - 0);
|
||||||
|
end
|
||||||
`endif
|
`endif
|
||||||
|
BHE = 0;
|
||||||
external_address_bus = 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;
|
||||||
we_jumped=0;
|
end
|
||||||
|
`PROC_IF_WRITE_CIR:begin
|
||||||
|
/*I built the entire decode stage with CIR
|
||||||
|
* being big endian so just convert it here*/
|
||||||
|
|
||||||
|
if(instruction_size==1)begin
|
||||||
|
/*Half on CIR half on this address */
|
||||||
|
state=`PROC_DE_STATE_ENTRY;
|
||||||
|
if(ProgCount[0:0]==1)begin
|
||||||
|
CIR = {CIR[7:0],external_data_bus[15:8]};
|
||||||
|
end else begin
|
||||||
|
CIR = {CIR[7:0],external_data_bus[7:0]};
|
||||||
|
end
|
||||||
|
ProgCount=ProgCount+1;
|
||||||
|
end else begin
|
||||||
|
if(ProgCount[0:0]==1)begin
|
||||||
|
/* Half on this address half on the next*/
|
||||||
|
ProgCount=ProgCount+1;
|
||||||
|
CIR[15:8] <= external_data_bus[15:8];
|
||||||
|
state=`PROC_IF_STATE_EXTRA_FETCH_SET;
|
||||||
|
end else begin
|
||||||
|
/* Both on this address! */
|
||||||
|
ProgCount=ProgCount+2;
|
||||||
|
CIR <= {external_data_bus[7:0],external_data_bus[15:8]};
|
||||||
|
state=`PROC_DE_STATE_ENTRY;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
`PROC_IF_STATE_EXTRA_FETCH_SET:begin
|
`PROC_IF_STATE_EXTRA_FETCH_SET:begin
|
||||||
ProgCount=ProgCount+1;
|
|
||||||
external_address_bus = ProgCount;
|
external_address_bus = ProgCount;
|
||||||
|
BHE=0;
|
||||||
state=`PROC_IF_STATE_EXTRA_FETCH;
|
state=`PROC_IF_STATE_EXTRA_FETCH;
|
||||||
end
|
end
|
||||||
|
`PROC_IF_STATE_EXTRA_FETCH:begin
|
||||||
|
CIR[7:0] <= external_data_bus[7:0];
|
||||||
|
ProgCount=ProgCount+1;
|
||||||
|
state=`PROC_DE_STATE_ENTRY;
|
||||||
|
end
|
||||||
`PROC_DE_STATE_ENTRY:begin
|
`PROC_DE_STATE_ENTRY:begin
|
||||||
/* If we are unaligned, the address bus contains the
|
|
||||||
* ProgCount and points to the second word containing
|
|
||||||
* the next unread byte in external_data_bus[7:0]. If
|
|
||||||
* we are aligned the address bus points to the first
|
|
||||||
* word of the instruction which contains no useful
|
|
||||||
* data anymore but the ProgCount has the correct
|
|
||||||
* address so update it now so that whatever the case
|
|
||||||
* external_data_bus contains at least some unknown data */
|
|
||||||
one_byte_instruction=(!has_operands)&&(!opcode_size);
|
|
||||||
external_address_bus = ProgCount;
|
external_address_bus = ProgCount;
|
||||||
if(SIMPLE_MICRO==0)begin
|
if(SIMPLE_MICRO==0)begin
|
||||||
|
/*This flag is set at reset and jump because
|
||||||
|
* at IF we need to know the size of the
|
||||||
|
* previous instruction (specificly if it was
|
||||||
|
* a single byte and the value would be
|
||||||
|
* incorrect in both cases. So when it gets
|
||||||
|
* set reset it only at the start of the next
|
||||||
|
* 8086 instruction */
|
||||||
|
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.
|
||||||
@ -299,7 +296,10 @@ always @(posedge clock) begin
|
|||||||
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;
|
||||||
state=`PROC_EX_STATE_ENTRY;
|
case(IN_MOD)
|
||||||
|
3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
|
||||||
|
default: state=`PROC_EX_STATE_ENTRY;
|
||||||
|
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
|
||||||
@ -314,44 +314,49 @@ always @(posedge clock) begin
|
|||||||
default: state=`PROC_EX_STATE_ENTRY;
|
default: state=`PROC_EX_STATE_ENTRY;
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin
|
||||||
if(unaligned_access==1)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]};
|
||||||
|
end else begin
|
||||||
|
PARAM1[7:0] = external_data_bus[15:8];
|
||||||
|
end
|
||||||
|
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
|
||||||
ProgCount=ProgCount+1;
|
|
||||||
case(IN_MOD)
|
|
||||||
3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
|
|
||||||
default: state=`PROC_EX_STATE_ENTRY;
|
|
||||||
endcase
|
|
||||||
end else begin
|
|
||||||
external_address_bus=ProgCount;
|
|
||||||
state=`PROC_DE_LOAD_8_PARAM_UNALIGNED;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
`PROC_DE_LOAD_16_PARAM:begin
|
|
||||||
if(opcode_size==0)begin
|
|
||||||
if(unaligned_access==1)begin
|
|
||||||
PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]};
|
|
||||||
ProgCount=ProgCount+1;
|
|
||||||
end else begin
|
|
||||||
PARAM1 = {external_data_bus[15:8],CIR[7:0]};
|
|
||||||
end
|
end
|
||||||
|
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 else begin
|
end
|
||||||
|
`PROC_DE_LOAD_16_PARAM:begin
|
||||||
|
if(opcode_size==0)begin
|
||||||
|
PARAM1[7:0] = CIR[7:0];
|
||||||
|
if(ProgCount[0:0]==1)begin
|
||||||
|
PARAM1[15:8] = external_data_bus[15:8];
|
||||||
|
end else begin
|
||||||
|
PARAM1[15:8] = external_data_bus[7:0];
|
||||||
|
end
|
||||||
ProgCount=ProgCount+1;
|
ProgCount=ProgCount+1;
|
||||||
if(unaligned_access==1)begin
|
case(IN_MOD)
|
||||||
PARAM1[7:0] = external_data_bus[7:0];
|
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;
|
state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET;
|
||||||
end else begin
|
end else begin
|
||||||
PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]};
|
PARAM1 = external_data_bus;
|
||||||
|
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;
|
||||||
@ -359,8 +364,13 @@ always @(posedge clock) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
`PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin
|
||||||
|
external_address_bus = ProgCount;
|
||||||
|
state=`PROC_DE_LOAD_16_EXTRA_FETCH;
|
||||||
|
end
|
||||||
`PROC_DE_LOAD_16_EXTRA_FETCH:begin
|
`PROC_DE_LOAD_16_EXTRA_FETCH:begin
|
||||||
PARAM1[15:8] = external_data_bus[15:8];
|
ProgCount=ProgCount+1;
|
||||||
|
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;
|
||||||
@ -422,27 +432,34 @@ always @(posedge clock) begin
|
|||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
end
|
end
|
||||||
endcase
|
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;
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_GET_ALIGNED_DATA:begin
|
`PROC_MEMIO_GET_ALIGNED_DATA:begin
|
||||||
PARAM2=(Wbit==1)? {external_data_bus[7:0],external_data_bus[15:8]} : {8'b00000000,external_data_bus[15:8]} ;
|
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'b00000000,external_data_bus[7:0]};
|
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
|
||||||
|
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;
|
||||||
|
end
|
||||||
`PROC_EX_STATE_ENTRY:begin
|
`PROC_EX_STATE_ENTRY:begin
|
||||||
FLAGS[7:0] = ALU_1FLAGS[7:0]; //TODO, we should probably move all the ...STATE_EXIT stuff here
|
external_address_bus = ProgCount;
|
||||||
/*Don't update the unaligned_access for Instruction
|
FLAGS[7:0] = ALU_1FLAGS[7:0];
|
||||||
* Fetch if we are doing microcode execution, it will
|
|
||||||
* be done by decode at the end*/
|
|
||||||
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
|
||||||
unaligned_access=unaligning_instruction^unaligned_access;
|
|
||||||
case(OUT_MOD)
|
case(OUT_MOD)
|
||||||
3'b000,
|
3'b000,
|
||||||
3'b001,
|
3'b001,
|
||||||
@ -499,9 +516,8 @@ always @(posedge clock) begin
|
|||||||
state=`PROC_NEXT_MICROCODE;
|
state=`PROC_NEXT_MICROCODE;
|
||||||
end
|
end
|
||||||
3'b101:begin /* Program Counter*/
|
3'b101:begin /* Program Counter*/
|
||||||
ProgCount={5'b00000,ALU_1O[15:1]};
|
ProgCount={5'b0000,ALU_1O[15:0]};
|
||||||
unaligned_access=ALU_1O[0:0];
|
instruction_size_init=1;
|
||||||
we_jumped=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
|
||||||
@ -521,45 +537,54 @@ 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 = {5'b00000,reg_read_port1_data[15:1]};
|
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_DATA:`PROC_MEMIO_PUT_ALIGNED_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_BYTE_STOP_READ:begin
|
`PROC_MEMIO_PUT_UNALIGNED_16BIT_DATA:begin
|
||||||
read=1;
|
|
||||||
state=`PROC_MEMIO_WRITE_EXIT;
|
|
||||||
if(reg_read_port1_data[0:0]==0)
|
|
||||||
data_bus_output_register={ALU_1O[7:0],BYTE_WRITE_TEMP_REG[7:0]};
|
|
||||||
else
|
|
||||||
data_bus_output_register={BYTE_WRITE_TEMP_REG[15:8],ALU_1O[7:0]};
|
|
||||||
end
|
|
||||||
`PROC_MEMIO_PUT_UNALIGNED_FIRST_BYTE:begin
|
|
||||||
read=1;
|
read=1;
|
||||||
|
BHE=0;
|
||||||
|
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;
|
||||||
data_bus_output_register={BYTE_WRITE_TEMP_REG[15:8],ALU_1O[7:0]};
|
end
|
||||||
|
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT:begin
|
||||||
|
write=0;
|
||||||
|
state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2;
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2:begin
|
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT2:begin
|
||||||
external_address_bus=external_address_bus+1;
|
|
||||||
write=1;
|
write=1;
|
||||||
read=0;
|
external_address_bus=external_address_bus+1;
|
||||||
state=`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT3;
|
BHE=1;
|
||||||
|
state=`PROC_MEMIO_WRITE_EXIT;
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_PUT_UNALIGNED_PREP_NEXT4:begin
|
`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;
|
||||||
|
end
|
||||||
|
`PROC_MEMIO_PUT_BYTE:begin
|
||||||
read=1;
|
read=1;
|
||||||
state=`PROC_MEMIO_WRITE_EXIT;
|
state=`PROC_MEMIO_WRITE_EXIT;
|
||||||
data_bus_output_register={ALU_1O[15:8],BYTE_WRITE_TEMP_REG[7:0]};
|
if(reg_read_port1_data[0:0]==0) begin
|
||||||
|
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};
|
||||||
|
end
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_GET_SECOND_BYTE1:begin
|
`PROC_MEMIO_WRITE_EXIT:begin
|
||||||
PARAM2[15:8]=external_data_bus[15:8];
|
write=0;
|
||||||
state=`PROC_EX_STATE_ENTRY;
|
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
||||||
|
state=`PROC_IF_STATE_ENTRY;
|
||||||
|
else
|
||||||
|
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;
|
||||||
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 == `UCODE_NO_INSTRUCTION )begin
|
if( ucode_seq_addr == `UCODE_NO_INSTRUCTION )begin
|
||||||
/*Finished microcode*/
|
/*Finished microcode*/
|
||||||
if(we_jumped==0)
|
|
||||||
unaligned_access=unaligning_instruction^unaligned_access;
|
|
||||||
SIMPLE_MICRO=0;
|
SIMPLE_MICRO=0;
|
||||||
state=`PROC_IF_STATE_ENTRY;
|
state=`PROC_IF_STATE_ENTRY;
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -27,9 +27,10 @@ wire [19:0]address_bus;
|
|||||||
wire [15:0]data_bus;
|
wire [15:0]data_bus;
|
||||||
wire rd,wr,romcs,HALT;
|
wire rd,wr,romcs,HALT;
|
||||||
wire ERROR;
|
wire ERROR;
|
||||||
|
wire IOMEM;
|
||||||
|
|
||||||
processor p(clock,reset,address_bus,data_bus,rd,wr,HALT,ERROR);
|
processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
|
||||||
mem sysmem(address_bus,data_bus,rd,wr,romcs);
|
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
||||||
|
|
||||||
`define CPU_SPEED 1000
|
`define CPU_SPEED 1000
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user