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
|
||||
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
|
||||
include common.mk
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
org 0x100
|
||||
INCLUDE brainfuck_compiler_v1.asm
|
||||
|
||||
prog:
|
||||
INCLUDE hello_9086.bf.asm
|
||||
output_program:
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
JMP AX
|
||||
|
@ -1,4 +1,9 @@
|
||||
ORG 0x100
|
||||
INCLUDE brainfuck_interpreter_v0.asm
|
||||
|
||||
prog:
|
||||
INCLUDE hello_9086.bf.asm
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
JMP AX
|
||||
|
@ -1,6 +1,11 @@
|
||||
ORG 0x100
|
||||
INCLUDE brainfuck_compiler_v1.asm
|
||||
|
||||
prog:
|
||||
INCLUDE mandelbrot.bf.asm
|
||||
|
||||
output_program:
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
JMP AX
|
||||
|
@ -35,7 +35,7 @@ disas: $(subst .txt,.disas,${BOOT_CODE})
|
||||
|
||||
# Assembling code
|
||||
%.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}xxd -ps -c 2 "$(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_OR: begin C_FLAG=0;OUT=A|B; end
|
||||
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
|
||||
default:begin
|
||||
OUT=0;
|
||||
C_FLAG=0;
|
||||
end
|
||||
`ALU_OP_SHIFT_LEFT: begin C_FLAG=(A&16'h8000)==16'h8000;OUT=A<<B; end
|
||||
endcase
|
||||
end else begin
|
||||
case (op)
|
||||
@ -52,10 +49,7 @@ always @ ( * ) begin
|
||||
`ALU_OP_AND: begin C_FLAG=0;OUT=A&B; end
|
||||
`ALU_OP_OR: begin C_FLAG=0;OUT=A|B; end
|
||||
`ALU_OP_XOR: begin C_FLAG=0;OUT=A^B; end
|
||||
default:begin
|
||||
OUT=0;
|
||||
C_FLAG=0;
|
||||
end
|
||||
`ALU_OP_SHIFT_LEFT: begin C_FLAG=(A&16'h80)==16'h80;OUT=A<<B; end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -25,3 +25,4 @@
|
||||
`define ALU_OP_XOR 3'b100
|
||||
`define ALU_OP_ADD_SIGNED_B 3'b101
|
||||
`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:
|
||||
MOV SP,#STACK
|
||||
MOV AX,#0x0000
|
||||
@ -37,3 +42,7 @@ RET
|
||||
|
||||
.BLKB 10
|
||||
STACK:
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
JMP AX
|
||||
|
@ -51,6 +51,7 @@ module decoder(
|
||||
,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 [2:0]instruction_size
|
||||
,output reg memio_address_select
|
||||
);
|
||||
// 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_write_addr={Wbit,3'b000};
|
||||
ALU_1OP=`ALU_OP_ADD;
|
||||
memio_address_select=0;
|
||||
if(Wbit)
|
||||
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||
else
|
||||
@ -135,6 +137,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
in_alu1_sel2=2'b00;
|
||||
end
|
||||
OUT_MOD=IN_MOD;
|
||||
memio_address_select=0;
|
||||
case({Sbit,Wbit})
|
||||
2'b00,2'b11:begin
|
||||
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;
|
||||
OUT_MOD=3'b100;
|
||||
ALU_1OP=`ALU_OP_SUB;
|
||||
memio_address_select=0;
|
||||
if(IN_MOD==3'b011)begin
|
||||
/*compare register with param*/
|
||||
in_alu1_sel2=2'b01;
|
||||
@ -209,6 +213,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
ALU_1OP=`ALU_OP_ADD;
|
||||
next_state=`PROC_EX_STATE_ENTRY;
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1011_1???_??? : begin
|
||||
/*MOV - Move Immediate word to register*/
|
||||
@ -224,6 +229,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
PARAM2=0;
|
||||
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1000_10??_??? : begin
|
||||
/* 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;
|
||||
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b0100_????_???:begin//DEC
|
||||
/* DEC - Decrement Register */
|
||||
@ -290,6 +297,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
ALU_1OP=`ALU_OP_SUB;
|
||||
next_state=`PROC_EX_STATE_ENTRY;
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1111_111?_00? : begin
|
||||
/* INC - Register/Memory */
|
||||
@ -316,6 +324,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
else
|
||||
next_state=`PROC_MEMIO_READ;
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1111_0100_??? : begin
|
||||
/* HLT - Halt */
|
||||
@ -327,7 +336,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
ERROR<=0;
|
||||
seq_addr_entry<=`UCODE_NO_INSTRUCTION;
|
||||
next_state=`PROC_HALT_STATE;
|
||||
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b0011_110?_??? : begin
|
||||
/* 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;
|
||||
end
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b0111_????_???:begin
|
||||
/* Conditional relative jumps */
|
||||
@ -408,6 +418,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
end
|
||||
endcase
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1110_1011_???:begin
|
||||
/* 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;
|
||||
next_state=`PROC_EX_STATE_ENTRY;
|
||||
`normal_instruction;
|
||||
end
|
||||
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;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1110_1000_???:begin
|
||||
/* CALL - Direct call within segment */
|
||||
@ -446,6 +446,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
Sbit=1;
|
||||
PARAM2=2; //subtract from sp
|
||||
seq_addr_entry<=`UCODE_CALL_ENTRY;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1100_0011_???:begin
|
||||
/* RET - Return from call within segment */
|
||||
@ -458,6 +459,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
Sbit=0;
|
||||
PARAM1=2;
|
||||
seq_addr_entry<=`UCODE_RET_ENTRY;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1010_101?_???:begin
|
||||
/* 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;
|
||||
seq_addr_entry<=`UCODE_STOS_ENTRY;
|
||||
PARAM2=(Wbit==1)?2:1;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b0101_0???_???:begin
|
||||
/* PUSH - SP-=2; [SP]=REG */
|
||||
@ -480,6 +483,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
PARAM2=2;
|
||||
reg_read_port2_addr={1'b1,CIR[10:8]};
|
||||
seq_addr_entry<=`UCODE_PUSH_ENTRY;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1111_011?_000:begin
|
||||
/* TEST - Bitwise AND affecting only flags */
|
||||
@ -508,6 +512,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
endcase
|
||||
OUT_MOD=3'b100;/*NULL*/
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b0101_1???_???:begin
|
||||
/* POP - REG=[SP]; SP+=2 */
|
||||
@ -519,6 +524,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
PARAM1=2;
|
||||
reg_write_addr={1'b1,CIR[10:8]};
|
||||
seq_addr_entry<=`UCODE_POP_ENTRY;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1111_1111_100:begin
|
||||
/* 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;
|
||||
OUT_MOD=3'b101;
|
||||
`normal_instruction;
|
||||
memio_address_select=0;
|
||||
end
|
||||
11'b1100_011?_000:begin
|
||||
/* MOV - Move immediate to register/memory */
|
||||
@ -560,6 +567,31 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
IN_MOD=3'b011;
|
||||
RM=CIR[2:0];
|
||||
`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
|
||||
default:begin
|
||||
`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
|
||||
//from when we ordered the switch to microcode
|
||||
seq_addr_entry <= ucode_data[`UCODE_ADDR_BITS-1:0];
|
||||
case(ucode_data[7:6])
|
||||
2'b00: next_state=`PROC_EX_STATE_ENTRY;
|
||||
2'b01: next_state=`PROC_DE_LOAD_16_PARAM;
|
||||
2'b10: next_state=`PROC_DE_LOAD_8_PARAM;
|
||||
2'b11: next_state=`PROC_MEMIO_READ;
|
||||
case(ucode_data[8:6])
|
||||
3'b000: next_state=`PROC_EX_STATE_ENTRY;
|
||||
3'b001: next_state=`PROC_DE_LOAD_16_PARAM;
|
||||
3'b010: next_state=`PROC_DE_LOAD_8_PARAM;
|
||||
3'b011: next_state=`PROC_MEMIO_READ;
|
||||
3'b100: next_state=`PROC_MEMIO_READ_SETADDR;
|
||||
default: begin end /*impossible*/
|
||||
endcase
|
||||
if(ucode_data[35:35]==0)
|
||||
reg_write_addr=ucode_data[11:8 ];
|
||||
in_alu1_sel1 =ucode_data[13:12];
|
||||
in_alu1_sel2 =ucode_data[15:14];
|
||||
OUT_MOD =ucode_data[18:16];
|
||||
if(ucode_data[36:36]==0)
|
||||
reg_write_addr=ucode_data[12:9 ];
|
||||
in_alu1_sel1 =ucode_data[14:13];
|
||||
in_alu1_sel2 =ucode_data[16:15];
|
||||
OUT_MOD =ucode_data[19:17];
|
||||
/*1:1 map essentially but I want to keep the spec for these bits separate
|
||||
* from the alu op select bits*/
|
||||
case(ucode_data[21:19])
|
||||
case(ucode_data[22:20])
|
||||
3'b000: ALU_1OP=`ALU_OP_ADD;
|
||||
3'b001: ALU_1OP=`ALU_OP_SUB;
|
||||
3'b010: ALU_1OP=`ALU_OP_AND;
|
||||
@ -591,15 +625,17 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
||||
3'b100: ALU_1OP=`ALU_OP_XOR;
|
||||
3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
|
||||
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
|
||||
3'b111: ALU_1OP=`ALU_OP_SHIFT_LEFT;
|
||||
default: begin end
|
||||
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)
|
||||
reg_read_port2_addr=ucode_data[32:29];
|
||||
if(ucode_data[37:37]==1)
|
||||
Wbit=ucode_data[36:36];
|
||||
reg_read_port1_addr=ucode_data[26:23];
|
||||
IN_MOD=ucode_data[29:27];
|
||||
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
|
||||
`undef invalid_instruction
|
||||
|
@ -57,6 +57,7 @@ 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;
|
||||
wire memio_address_select;
|
||||
|
||||
decoder decoder(
|
||||
.CIR(CIR),
|
||||
@ -76,7 +77,8 @@ decoder decoder(
|
||||
.seq_addr_entry(ucode_seq_addr_entry),
|
||||
.SIMPLE_MICRO(SIMPLE_MICRO),
|
||||
.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];
|
||||
@ -194,7 +196,7 @@ always @(posedge clock) begin
|
||||
case(state)
|
||||
`PROC_RESET:begin
|
||||
ucode_seq_addr <= `UCODE_NO_INSTRUCTION;
|
||||
ProgCount <= 0;//TODO: Reset Vector
|
||||
ProgCount <= 'hFFF0;//TODO: Implement Segmentation and set to zero
|
||||
HALT <= 0;
|
||||
ERROR <= 0;
|
||||
IOMEM <= 0;
|
||||
@ -438,7 +440,10 @@ always @(posedge clock) begin
|
||||
endcase
|
||||
end
|
||||
`PROC_MEMIO_READ_SETADDR:begin
|
||||
if(memio_address_select==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;
|
||||
end
|
||||
`PROC_MEMIO_GET_ALIGNED_DATA:begin
|
||||
@ -531,6 +536,13 @@ always @(posedge clock) begin
|
||||
reg_read_port1_addr <= 4'b1100;
|
||||
state <= `PROC_MEMIO_WRITE;
|
||||
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
|
||||
`invalid_instruction
|
||||
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);
|
||||
processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
|
||||
|
||||
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
||||
|
||||
string waveform_name;
|
||||
|
@ -17,6 +17,8 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
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
|
||||
//
|
||||
//krs: Keep registers, selects weather the register port 1 and/or 2
|
||||
@ -38,8 +40,9 @@
|
||||
// 100:ALU_OP_XOR
|
||||
// 101:ALU_OP_ADD_SIGNED_B
|
||||
// 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
|
||||
//
|
||||
@ -48,38 +51,49 @@
|
||||
//rwa: Register Write Address
|
||||
//
|
||||
//nxs: Next State
|
||||
// 00: PROC_EX_STATE_ENTRY
|
||||
// 01: PROC_DE_LOAD_16_PARAM
|
||||
// 10: PROC_DE_LOAD_8_PARAM
|
||||
// 11: PROC_MEMIO_READ
|
||||
// 000: PROC_EX_STATE_ENTRY
|
||||
// 001: PROC_DE_LOAD_16_PARAM
|
||||
// 010: PROC_DE_LOAD_8_PARAM
|
||||
// 011: PROC_MEMIO_READ
|
||||
// 100: PROC_MEMIO_READ_SETADDR (used when addressing based on ALU_OUT
|
||||
//
|
||||
//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
|
||||
// CALL
|
||||
// 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)
|
||||
@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]
|
||||
@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
|
||||
|
||||
// RET
|
||||
// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||
@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]
|
||||
// 39 38 36 33 29 26 22 19 16 14 12 8 5 0
|
||||
// INT
|
||||
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||
@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)
|
||||
@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]
|
||||
/* 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
|
||||
@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
|
||||
@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
|
||||
|
||||
// POP
|
||||
// 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
|
||||
@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
|
||||
// mas|wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
|
||||
@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 __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
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
`define UCODE_SIZE 12
|
||||
`define UCODE_DATA_BITS 38
|
||||
`define UCODE_SIZE 17
|
||||
`define UCODE_DATA_BITS 40
|
||||
`define UCODE_ADDR_BITS $clog2(`UCODE_SIZE)
|
||||
|
||||
/* DEFINE ADDRESSES IN THE MICROCODE */
|
||||
`define UCODE_NO_INSTRUCTION 4'b0000
|
||||
`define UCODE_CALL_ENTRY 4'b0001
|
||||
`define UCODE_RET_ENTRY 4'b0100
|
||||
`define UCODE_STOS_ENTRY 4'b0110
|
||||
`define UCODE_PUSH_ENTRY 4'b1000
|
||||
`define UCODE_POP_ENTRY 4'b1010
|
||||
`define UCODE_NO_INSTRUCTION 5'b00000
|
||||
`define UCODE_CALL_ENTRY 5'b00001
|
||||
`define UCODE_RET_ENTRY 5'b00100
|
||||
`define UCODE_STOS_ENTRY 5'b00110
|
||||
`define UCODE_PUSH_ENTRY 5'b01000
|
||||
`define UCODE_POP_ENTRY 5'b01010
|
||||
`define UCODE_INT_ENTRY 5'b01100
|
||||
|
Loading…
Reference in New Issue
Block a user