Added partial support for the software interrupt INT instruction
This commit is contained in:
parent
d93c92c005
commit
9de83fd7c1
3
Makefile
3
Makefile
@ -23,6 +23,9 @@ GTKWSAVE=./gtkwave_savefile.gtkw
|
|||||||
MICROCODE=system/ucode.txt
|
MICROCODE=system/ucode.txt
|
||||||
BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt ${BOOT_CODE}
|
BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt ${BOOT_CODE}
|
||||||
|
|
||||||
|
shim:
|
||||||
|
@echo The processor\'s output handling is being rewritten so the usual mandelbrot program isn\'t working. please git checkout d93c92c00572d812c76d1b42969741d8cfce8d4d
|
||||||
|
|
||||||
NO_ASM=1
|
NO_ASM=1
|
||||||
include common.mk
|
include common.mk
|
||||||
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
org 0x100
|
||||||
INCLUDE brainfuck_compiler_v1.asm
|
INCLUDE brainfuck_compiler_v1.asm
|
||||||
|
|
||||||
prog:
|
prog:
|
||||||
INCLUDE hello_9086.bf.asm
|
INCLUDE hello_9086.bf.asm
|
||||||
output_program:
|
output_program:
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
ORG 0x100
|
||||||
INCLUDE brainfuck_interpreter_v0.asm
|
INCLUDE brainfuck_interpreter_v0.asm
|
||||||
|
|
||||||
prog:
|
prog:
|
||||||
INCLUDE hello_9086.bf.asm
|
INCLUDE hello_9086.bf.asm
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
|
ORG 0x100
|
||||||
INCLUDE brainfuck_compiler_v1.asm
|
INCLUDE brainfuck_compiler_v1.asm
|
||||||
|
|
||||||
prog:
|
prog:
|
||||||
INCLUDE mandelbrot.bf.asm
|
INCLUDE mandelbrot.bf.asm
|
||||||
|
|
||||||
output_program:
|
output_program:
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
@ -35,7 +35,7 @@ disas: $(subst .txt,.disas,${BOOT_CODE})
|
|||||||
|
|
||||||
# Assembling code
|
# Assembling code
|
||||||
%.txt:%.bin
|
%.txt:%.bin
|
||||||
${Q}dd if=/dev/zero bs=1 count=32768 of="$(subst .bin,.stage,$<)" status=none
|
${Q}dd if=/dev/zero bs=1 count=65536 of="$(subst .bin,.stage,$<)" status=none
|
||||||
${Q}dd if="$<" of="$(subst .bin,.stage,$<)" conv=notrunc,nocreat status=none
|
${Q}dd if="$<" of="$(subst .bin,.stage,$<)" conv=notrunc,nocreat status=none
|
||||||
${Q}xxd -ps -c 2 "$(subst .bin,.stage,$<)" > "$@"
|
${Q}xxd -ps -c 2 "$(subst .bin,.stage,$<)" > "$@"
|
||||||
${Q}rm "$(subst .bin,.stage,$<)"
|
${Q}rm "$(subst .bin,.stage,$<)"
|
||||||
|
10
system/alu.v
10
system/alu.v
@ -38,10 +38,7 @@ always @ ( * ) begin
|
|||||||
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
|
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
|
||||||
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
|
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
|
||||||
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
|
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
|
||||||
default:begin
|
`ALU_OP_SHIFT_LEFT: begin C_FLAG=(A&16'h8000)==16'h8000;OUT=A<<B; end
|
||||||
OUT=0;
|
|
||||||
C_FLAG=0;
|
|
||||||
end
|
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin
|
||||||
case (op)
|
case (op)
|
||||||
@ -52,10 +49,7 @@ always @ ( * ) begin
|
|||||||
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
|
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
|
||||||
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
|
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
|
||||||
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
|
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
|
||||||
default:begin
|
`ALU_OP_SHIFT_LEFT: begin C_FLAG=(A&16'h80)==16'h80;OUT=A<<B; end
|
||||||
OUT=0;
|
|
||||||
C_FLAG=0;
|
|
||||||
end
|
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -25,3 +25,4 @@
|
|||||||
`define ALU_OP_XOR 3'b100
|
`define ALU_OP_XOR 3'b100
|
||||||
`define ALU_OP_ADD_SIGNED_B 3'b101
|
`define ALU_OP_ADD_SIGNED_B 3'b101
|
||||||
`define ALU_OP_SUB_REVERSE 3'b110
|
`define ALU_OP_SUB_REVERSE 3'b110
|
||||||
|
`define ALU_OP_SHIFT_LEFT 3'b111
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
.ORG 0x84 /* INT 21 */
|
||||||
|
DW 0xFFFF /*Code Segment*/
|
||||||
|
DW 0x014c /*Program Counter*/
|
||||||
|
|
||||||
|
.ORG 0x0100
|
||||||
start:
|
start:
|
||||||
MOV SP,#STACK
|
MOV SP,#STACK
|
||||||
MOV AX,#0x0000
|
MOV AX,#0x0000
|
||||||
@ -37,3 +42,7 @@ RET
|
|||||||
|
|
||||||
.BLKB 10
|
.BLKB 10
|
||||||
STACK:
|
STACK:
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
@ -51,6 +51,7 @@ module decoder(
|
|||||||
,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
|
,output reg [2:0]instruction_size
|
||||||
|
,output reg memio_address_select
|
||||||
);
|
);
|
||||||
// verilator lint_on UNUSEDSIGNAL
|
// verilator lint_on UNUSEDSIGNAL
|
||||||
|
|
||||||
@ -109,6 +110,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
reg_read_port2_addr={Wbit,3'b000};
|
reg_read_port2_addr={Wbit,3'b000};
|
||||||
reg_write_addr={Wbit,3'b000};
|
reg_write_addr={Wbit,3'b000};
|
||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_1OP=`ALU_OP_ADD;
|
||||||
|
memio_address_select=0;
|
||||||
if(Wbit)
|
if(Wbit)
|
||||||
next_state=`PROC_DE_LOAD_16_PARAM;
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
else
|
else
|
||||||
@ -135,6 +137,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu1_sel2=2'b00;
|
in_alu1_sel2=2'b00;
|
||||||
end
|
end
|
||||||
OUT_MOD=IN_MOD;
|
OUT_MOD=IN_MOD;
|
||||||
|
memio_address_select=0;
|
||||||
case({Sbit,Wbit})
|
case({Sbit,Wbit})
|
||||||
2'b00,2'b11:begin
|
2'b00,2'b11:begin
|
||||||
next_state=`PROC_DE_LOAD_8_PARAM;
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
@ -180,6 +183,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;
|
||||||
|
memio_address_select=0;
|
||||||
if(IN_MOD==3'b011)begin
|
if(IN_MOD==3'b011)begin
|
||||||
/*compare register with param*/
|
/*compare register with param*/
|
||||||
in_alu1_sel2=2'b01;
|
in_alu1_sel2=2'b01;
|
||||||
@ -209,6 +213,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_1OP=`ALU_OP_ADD;
|
||||||
next_state=`PROC_EX_STATE_ENTRY;
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1011_1???_??? : begin
|
11'b1011_1???_??? : begin
|
||||||
/*MOV - Move Immediate word to register*/
|
/*MOV - Move Immediate word to register*/
|
||||||
@ -224,6 +229,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
PARAM2=0;
|
PARAM2=0;
|
||||||
next_state=`PROC_DE_LOAD_16_PARAM;
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1000_10??_??? : begin
|
11'b1000_10??_??? : begin
|
||||||
/* MOV - Reg/Mem to/from register */
|
/* MOV - Reg/Mem to/from register */
|
||||||
@ -268,6 +274,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_1OP=`ALU_OP_ADD;
|
||||||
|
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b0100_????_???:begin//DEC
|
11'b0100_????_???:begin//DEC
|
||||||
/* DEC - Decrement Register */
|
/* DEC - Decrement Register */
|
||||||
@ -290,6 +297,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
ALU_1OP=`ALU_OP_SUB;
|
ALU_1OP=`ALU_OP_SUB;
|
||||||
next_state=`PROC_EX_STATE_ENTRY;
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1111_111?_00? : begin
|
11'b1111_111?_00? : begin
|
||||||
/* INC - Register/Memory */
|
/* INC - Register/Memory */
|
||||||
@ -316,6 +324,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
else
|
else
|
||||||
next_state=`PROC_MEMIO_READ;
|
next_state=`PROC_MEMIO_READ;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1111_0100_??? : begin
|
11'b1111_0100_??? : begin
|
||||||
/* HLT - Halt */
|
/* HLT - Halt */
|
||||||
@ -327,7 +336,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
ERROR<=0;
|
ERROR<=0;
|
||||||
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
|
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
|
||||||
next_state=`PROC_HALT_STATE;
|
next_state=`PROC_HALT_STATE;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b0011_110?_??? : begin
|
11'b0011_110?_??? : begin
|
||||||
/* CMP - Compare Immediate with accumulator */
|
/* CMP - Compare Immediate with accumulator */
|
||||||
@ -355,6 +364,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
next_state=`PROC_EX_STATE_ENTRY;
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
end
|
end
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b0111_????_???:begin
|
11'b0111_????_???:begin
|
||||||
/* Conditional relative jumps */
|
/* Conditional relative jumps */
|
||||||
@ -408,6 +418,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1110_1011_???:begin
|
11'b1110_1011_???:begin
|
||||||
/* JMP - Unconditional jump direct within segment (short) */
|
/* JMP - Unconditional jump direct within segment (short) */
|
||||||
@ -422,18 +433,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
OUT_MOD=3'b101;
|
OUT_MOD=3'b101;
|
||||||
next_state=`PROC_EX_STATE_ENTRY;
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
end
|
memio_address_select=0;
|
||||||
11'b1100_1101_???:begin
|
|
||||||
/* INT - execute interrupt handler */
|
|
||||||
/* 1 1 0 0 1 1 0 1 | DATA |*/
|
|
||||||
instruction_size=2;
|
|
||||||
opcode_size=0;
|
|
||||||
/* Emulate MS-DOS print routines */
|
|
||||||
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*/
|
|
||||||
end
|
|
||||||
next_state=`PROC_IF_STATE_ENTRY;
|
|
||||||
`normal_instruction;
|
|
||||||
end
|
end
|
||||||
11'b1110_1000_???:begin
|
11'b1110_1000_???:begin
|
||||||
/* CALL - Direct call within segment */
|
/* CALL - Direct call within segment */
|
||||||
@ -446,6 +446,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
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;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1100_0011_???:begin
|
11'b1100_0011_???:begin
|
||||||
/* RET - Return from call within segment */
|
/* RET - Return from call within segment */
|
||||||
@ -458,6 +459,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
Sbit=0;
|
Sbit=0;
|
||||||
PARAM1=2;
|
PARAM1=2;
|
||||||
seq_addr_entry<=`UCODE_RET_ENTRY;
|
seq_addr_entry<=`UCODE_RET_ENTRY;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1010_101?_???:begin
|
11'b1010_101?_???:begin
|
||||||
/* STOS - Write byte/word to [DI] and increment accordingly */
|
/* STOS - Write byte/word to [DI] and increment accordingly */
|
||||||
@ -469,6 +471,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
RM=3'b101;
|
RM=3'b101;
|
||||||
seq_addr_entry<=`UCODE_STOS_ENTRY;
|
seq_addr_entry<=`UCODE_STOS_ENTRY;
|
||||||
PARAM2=(Wbit==1)?2:1;
|
PARAM2=(Wbit==1)?2:1;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b0101_0???_???:begin
|
11'b0101_0???_???:begin
|
||||||
/* PUSH - SP-=2; [SP]=REG */
|
/* PUSH - SP-=2; [SP]=REG */
|
||||||
@ -480,6 +483,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
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;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1111_011?_000:begin
|
11'b1111_011?_000:begin
|
||||||
/* TEST - Bitwise AND affecting only flags */
|
/* TEST - Bitwise AND affecting only flags */
|
||||||
@ -508,6 +512,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
endcase
|
endcase
|
||||||
OUT_MOD=3'b100;/*NULL*/
|
OUT_MOD=3'b100;/*NULL*/
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b0101_1???_???:begin
|
11'b0101_1???_???:begin
|
||||||
/* POP - REG=[SP]; SP+=2 */
|
/* POP - REG=[SP]; SP+=2 */
|
||||||
@ -519,6 +524,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
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;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1111_1111_100:begin
|
11'b1111_1111_100:begin
|
||||||
/* JMP - Unconditional indirect within segment jump */
|
/* JMP - Unconditional indirect within segment jump */
|
||||||
@ -540,6 +546,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
ALU_1OP=`ALU_OP_ADD;
|
ALU_1OP=`ALU_OP_ADD;
|
||||||
OUT_MOD=3'b101;
|
OUT_MOD=3'b101;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
11'b1100_011?_000:begin
|
11'b1100_011?_000:begin
|
||||||
/* MOV - Move immediate to register/memory */
|
/* MOV - Move immediate to register/memory */
|
||||||
@ -560,6 +567,31 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
IN_MOD=3'b011;
|
IN_MOD=3'b011;
|
||||||
RM=CIR[2:0];
|
RM=CIR[2:0];
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
|
memio_address_select=0;
|
||||||
|
end
|
||||||
|
11'b1100_1101_???:begin
|
||||||
|
/* INT - execute interrupt handler */
|
||||||
|
/* 1 1 0 0 1 1 0 1 | DATA |*/
|
||||||
|
// [skiped] 1) push flags
|
||||||
|
// [skiped] 2) clear trap and interrupt enable flag
|
||||||
|
// [skiped] 3) push CS
|
||||||
|
// [skiped] 4) fetch CS from interrupt table
|
||||||
|
// 5) push ProgCount
|
||||||
|
// 6) fetch ProgCount from interrupt table
|
||||||
|
instruction_size=2;
|
||||||
|
opcode_size=0;
|
||||||
|
Wbit=1;
|
||||||
|
Sbit=0;
|
||||||
|
PARAM2=2;
|
||||||
|
seq_addr_entry<=`UCODE_INT_ENTRY;
|
||||||
|
memio_address_select=0;
|
||||||
|
///* Emulate MS-DOS print routines */
|
||||||
|
//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*/
|
||||||
|
//end
|
||||||
|
//next_state=`PROC_IF_STATE_ENTRY;
|
||||||
|
//`normal_instruction;
|
||||||
|
//memio_address_select=0;
|
||||||
end
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
@ -570,20 +602,22 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
//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[`UCODE_ADDR_BITS-1:0];
|
||||||
case(ucode_data[7:6])
|
case(ucode_data[8:6])
|
||||||
2'b00: next_state=`PROC_EX_STATE_ENTRY;
|
3'b000: next_state=`PROC_EX_STATE_ENTRY;
|
||||||
2'b01: next_state=`PROC_DE_LOAD_16_PARAM;
|
3'b001: next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
2'b10: next_state=`PROC_DE_LOAD_8_PARAM;
|
3'b010: next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
2'b11: next_state=`PROC_MEMIO_READ;
|
3'b011: next_state=`PROC_MEMIO_READ;
|
||||||
|
3'b100: next_state=`PROC_MEMIO_READ_SETADDR;
|
||||||
|
default: begin end /*impossible*/
|
||||||
endcase
|
endcase
|
||||||
if(ucode_data[35:35]==0)
|
if(ucode_data[36:36]==0)
|
||||||
reg_write_addr=ucode_data[11:8 ];
|
reg_write_addr=ucode_data[12:9 ];
|
||||||
in_alu1_sel1 =ucode_data[13:12];
|
in_alu1_sel1 =ucode_data[14:13];
|
||||||
in_alu1_sel2 =ucode_data[15:14];
|
in_alu1_sel2 =ucode_data[16:15];
|
||||||
OUT_MOD =ucode_data[18:16];
|
OUT_MOD =ucode_data[19:17];
|
||||||
/*1:1 map essentially but I want to keep the spec for these bits separate
|
/*1:1 map essentially but I want to keep the spec for these bits separate
|
||||||
* from the alu op select bits*/
|
* from the alu op select bits*/
|
||||||
case(ucode_data[21:19])
|
case(ucode_data[22:20])
|
||||||
3'b000: ALU_1OP=`ALU_OP_ADD;
|
3'b000: ALU_1OP=`ALU_OP_ADD;
|
||||||
3'b001: ALU_1OP=`ALU_OP_SUB;
|
3'b001: ALU_1OP=`ALU_OP_SUB;
|
||||||
3'b010: ALU_1OP=`ALU_OP_AND;
|
3'b010: ALU_1OP=`ALU_OP_AND;
|
||||||
@ -591,15 +625,17 @@ 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;
|
||||||
|
3'b111: ALU_1OP=`ALU_OP_SHIFT_LEFT;
|
||||||
default: begin end
|
default: begin end
|
||||||
endcase
|
endcase
|
||||||
if(ucode_data[33:33]==0)
|
|
||||||
reg_read_port1_addr=ucode_data[25:22];
|
|
||||||
IN_MOD=ucode_data[28:26];
|
|
||||||
if(ucode_data[34:34]==0)
|
if(ucode_data[34:34]==0)
|
||||||
reg_read_port2_addr=ucode_data[32:29];
|
reg_read_port1_addr=ucode_data[26:23];
|
||||||
if(ucode_data[37:37]==1)
|
IN_MOD=ucode_data[29:27];
|
||||||
Wbit=ucode_data[36:36];
|
if(ucode_data[35:35]==0)
|
||||||
|
reg_read_port2_addr=ucode_data[33:30];
|
||||||
|
if(ucode_data[38:38]==1)
|
||||||
|
Wbit=ucode_data[37:37];
|
||||||
|
memio_address_select=ucode_data[39:39];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
`undef invalid_instruction
|
`undef invalid_instruction
|
||||||
|
@ -57,6 +57,7 @@ wire [2:0] DE_instruction_size;
|
|||||||
reg instruction_size_init;
|
reg instruction_size_init;
|
||||||
wire [2:0] instruction_size;
|
wire [2:0] instruction_size;
|
||||||
assign instruction_size = instruction_size_init ? 3'b010 : DE_instruction_size;
|
assign instruction_size = instruction_size_init ? 3'b010 : DE_instruction_size;
|
||||||
|
wire memio_address_select;
|
||||||
|
|
||||||
decoder decoder(
|
decoder decoder(
|
||||||
.CIR(CIR),
|
.CIR(CIR),
|
||||||
@ -76,7 +77,8 @@ decoder decoder(
|
|||||||
.seq_addr_entry(ucode_seq_addr_entry),
|
.seq_addr_entry(ucode_seq_addr_entry),
|
||||||
.SIMPLE_MICRO(SIMPLE_MICRO),
|
.SIMPLE_MICRO(SIMPLE_MICRO),
|
||||||
.seq_addr_input(ucode_seq_addr),
|
.seq_addr_input(ucode_seq_addr),
|
||||||
.instruction_size(DE_instruction_size)
|
.instruction_size(DE_instruction_size),
|
||||||
|
.memio_address_select(memio_address_select)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign Wbit=INSTRUCTION_INFO[2:2];
|
assign Wbit=INSTRUCTION_INFO[2:2];
|
||||||
@ -194,7 +196,7 @@ always @(posedge clock) begin
|
|||||||
case(state)
|
case(state)
|
||||||
`PROC_RESET:begin
|
`PROC_RESET:begin
|
||||||
ucode_seq_addr <= `UCODE_NO_INSTRUCTION;
|
ucode_seq_addr <= `UCODE_NO_INSTRUCTION;
|
||||||
ProgCount <= 0;//TODO: Reset Vector
|
ProgCount <= 'hFFF0;//TODO: Implement Segmentation and set to zero
|
||||||
HALT <= 0;
|
HALT <= 0;
|
||||||
ERROR <= 0;
|
ERROR <= 0;
|
||||||
IOMEM <= 0;
|
IOMEM <= 0;
|
||||||
@ -438,7 +440,10 @@ always @(posedge clock) begin
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
`PROC_MEMIO_READ_SETADDR:begin
|
`PROC_MEMIO_READ_SETADDR:begin
|
||||||
|
if(memio_address_select==0)
|
||||||
external_address_bus <= {4'b0,reg_read_port1_data[15:0]};
|
external_address_bus <= {4'b0,reg_read_port1_data[15:0]};
|
||||||
|
else
|
||||||
|
external_address_bus <= {4'b0,ALU_1O};
|
||||||
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
|
||||||
@ -531,6 +536,13 @@ always @(posedge clock) begin
|
|||||||
reg_read_port1_addr <= 4'b1100;
|
reg_read_port1_addr <= 4'b1100;
|
||||||
state <= `PROC_MEMIO_WRITE;
|
state <= `PROC_MEMIO_WRITE;
|
||||||
end
|
end
|
||||||
|
3'b111:begin /* Write to PRAM1 (for microcode calculations) */
|
||||||
|
PARAM1 <= ALU_1O;
|
||||||
|
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
||||||
|
state <= `PROC_IF_STATE_ENTRY;
|
||||||
|
else
|
||||||
|
state <= `PROC_NEXT_MICROCODE;
|
||||||
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
end
|
end
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
module system ( input clock,input reset, output [19:0]address_bus, inout [15:0]data_bus,output BHE, output rd, output wr, output IOMEM, output HALT, output ERROR);
|
module system ( input clock,input reset, output [19:0]address_bus, inout [15:0]data_bus,output BHE, output rd, output wr, output IOMEM, output HALT, output ERROR);
|
||||||
processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
|
processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
|
||||||
|
|
||||||
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
||||||
|
|
||||||
string waveform_name;
|
string waveform_name;
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
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/>. */
|
||||||
|
|
||||||
|
//mas: MemIo Address Select
|
||||||
|
// 0: register file output 1: alu output
|
||||||
//wbo: Wbit overwrite, {VALUE,ENABLE}. ex 11 would force one, 10 wouldn't do anything
|
//wbo: Wbit overwrite, {VALUE,ENABLE}. ex 11 would force one, 10 wouldn't do anything
|
||||||
//
|
//
|
||||||
//krs: Keep registers, selects weather the register port 1 and/or 2
|
//krs: Keep registers, selects weather the register port 1 and/or 2
|
||||||
@ -38,8 +40,9 @@
|
|||||||
// 100:ALU_OP_XOR
|
// 100:ALU_OP_XOR
|
||||||
// 101:ALU_OP_ADD_SIGNED_B
|
// 101:ALU_OP_ADD_SIGNED_B
|
||||||
// 110:ALU_OP_SUB_REVERSE
|
// 110:ALU_OP_SUB_REVERSE
|
||||||
|
// 111:ALU_OP_SHIFT_LEFT
|
||||||
//
|
//
|
||||||
//a1o: OUT_MOD. Handled in `PROC_EX_STATE_EXIT
|
//a1o: OUT_MOD. Handled in `PROC_EX_STATE_ENTRY
|
||||||
//
|
//
|
||||||
//a12: In ALU 1 sel 2
|
//a12: In ALU 1 sel 2
|
||||||
//
|
//
|
||||||
@ -48,38 +51,49 @@
|
|||||||
//rwa: Register Write Address
|
//rwa: Register Write Address
|
||||||
//
|
//
|
||||||
//nxs: Next State
|
//nxs: Next State
|
||||||
// 00: PROC_EX_STATE_ENTRY
|
// 000: PROC_EX_STATE_ENTRY
|
||||||
// 01: PROC_DE_LOAD_16_PARAM
|
// 001: PROC_DE_LOAD_16_PARAM
|
||||||
// 10: PROC_DE_LOAD_8_PARAM
|
// 010: PROC_DE_LOAD_8_PARAM
|
||||||
// 11: PROC_MEMIO_READ
|
// 011: PROC_MEMIO_READ
|
||||||
|
// 100: PROC_MEMIO_READ_SETADDR (used when addressing based on ALU_OUT
|
||||||
//
|
//
|
||||||
//Nxt M: Next microcode address
|
//Nxt M: Next microcode address
|
||||||
|
|
||||||
@000 _00_000_0000_000_0000_000_000__00__00_0000__00_000000
|
|
||||||
|
|
||||||
// 36 34 32 28 25 21 18 15 13 11 7 5 0
|
// 39 38 36 33 29 26 22 19 16 14 12 8 5 0
|
||||||
// CALL
|
// INT
|
||||||
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
@001 _00_000_0000_011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
@00c __0__00_000_0000_011_1100_001_011__00__01_1100_010_001101 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
||||||
@002 _00_000_0000_011_xxxx_000_110__10__11_xxxx__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
|
@00d __0__00_000_0000_011_xxxx_000_110__10__11_xxxx_000_001110 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
|
||||||
@003 _00_000_0000_011_xxxx_000_101__10__00_xxxx__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
|
/* We read the parameter and get the address to jump on ALU_OUT */
|
||||||
|
@00e __0__00_000_xxxx_011_xxxx_111_111__00__00_xxxx_000_001111 // ALU_1: PARAM1 (arg) ALU_2: PARAM2 (2) ALU_OP:SHIFT ALU_out: PARAM1
|
||||||
// RET
|
@00f __1__00_000_xxxx_011_xxxx_000_100__00__00_xxxx_100_010000 // ALU_1: PARAM1 (base int table addr) ALU_2: PARAM2 (2) ALU_OP:ADD ALU_out: NULL
|
||||||
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
@010 __0__00_000_xxxx_011_xxxx_000_101__00__11_xxxx_000_000000 // ALU_1: 0 ALU_2: PARAM2 (address) ALU_OP:SHIFT ALU_out: PC
|
||||||
@004 _00_000_0000_110_xxxx_000_101__00__11_xxxx__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
|
|
||||||
@005 _00_000_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
|
|
||||||
|
|
||||||
// STOS
|
|
||||||
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
|
||||||
@006 _00_000_1000_011_xxxx_000_000__01__11_xxxx__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
|
|
||||||
@007 _11_000_xxxx_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
|
|
||||||
|
|
||||||
// PUSH
|
|
||||||
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
|
||||||
@008 _00_010_0000_011_1100_001_011__00__01_1100__00_001001 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
|
||||||
@009 _00_010_0000_011_xxxx_000_110__01__11_xxxx__00_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP]
|
|
||||||
|
|
||||||
// POP
|
// POP
|
||||||
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
@00a _00_100_0000_110_xxxx_011_011__00__11_xxxx__11_001011 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: REG
|
@00a __0__00_100_0000_110_xxxx_011_011__00__11_xxxx_011_001011 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: REG
|
||||||
@00b _00_000_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
|
@00b __0__00_000_1100_011_0000_000_011__01__00_1100_000_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
|
||||||
|
|
||||||
|
// PUSH
|
||||||
|
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
|
@008 __0__00_010_0000_011_1100_001_011__00__01_1100_000_001001 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
||||||
|
@009 __0__00_010_0000_011_xxxx_000_110__01__11_xxxx_000_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP]
|
||||||
|
|
||||||
|
// STOS
|
||||||
|
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
|
@006 __0__00_000_1000_011_xxxx_000_000__01__11_xxxx_000_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI]
|
||||||
|
@007 __0__11_000_xxxx_011_1111_000_011__00__01_1111_000_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI
|
||||||
|
|
||||||
|
// RET
|
||||||
|
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
|
@004 __0__00_000_0000_110_xxxx_000_101__00__11_xxxx_011_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP]) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2)
|
||||||
|
@005 __0__00_000_1100_011_0000_000_011__01__00_1100_000_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP
|
||||||
|
|
||||||
|
// CALL
|
||||||
|
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||||
|
@001 __0__00_000_0000_011_1100_001_011__00__01_1100_001_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1)
|
||||||
|
@002 __0__00_000_0000_011_xxxx_000_110__10__11_xxxx_000_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
|
||||||
|
@003 __0__00_000_0000_011_xxxx_000_101__10__00_xxxx_000_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
|
||||||
|
|
||||||
|
@000 __0__00_000_0000_000_0000_000_000__00__00_0000_000_000000
|
||||||
|
@ -17,14 +17,15 @@
|
|||||||
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_SIZE 17
|
||||||
`define UCODE_DATA_BITS 38
|
`define UCODE_DATA_BITS 40
|
||||||
`define UCODE_ADDR_BITS $clog2(`UCODE_SIZE)
|
`define UCODE_ADDR_BITS $clog2(`UCODE_SIZE)
|
||||||
|
|
||||||
/* 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
|
||||||
|
`define UCODE_INT_ENTRY 5'b01100
|
||||||
|
Loading…
Reference in New Issue
Block a user