Added support for some more instructions, fixed a bug in CMP and also added a program that uses them
This commit is contained in:
parent
64f5da82b0
commit
021dd06e9a
8
.gitignore
vendored
8
.gitignore
vendored
@ -6,12 +6,8 @@
|
|||||||
*.swp
|
*.swp
|
||||||
*.memdump
|
*.memdump
|
||||||
*.json
|
*.json
|
||||||
boot_code/brainfuck_interpreted.bin
|
boot_code/*.bin
|
||||||
boot_code/brainfuck_interpreted.txt
|
boot_code/*.txt
|
||||||
boot_code/brainfuck_mandelbrot.bin
|
|
||||||
boot_code/brainfuck_mandelbrot.txt
|
|
||||||
boot_code/brainfuck_compiled.bin
|
|
||||||
boot_code/brainfuck_compiled.txt
|
|
||||||
system/boot_code.bin
|
system/boot_code.bin
|
||||||
system/boot_code.txt
|
system/boot_code.txt
|
||||||
system/obj_dir/
|
system/obj_dir/
|
||||||
|
2
Makefile
2
Makefile
@ -21,7 +21,7 @@ VERILATOR_BIN=system/obj_dir/Vsystem
|
|||||||
BOOT_CODE=boot_code/brainfuck_mandelbrot.txt
|
BOOT_CODE=boot_code/brainfuck_mandelbrot.txt
|
||||||
GTKWSAVE=./gtkwave_savefile.gtkw
|
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/pipeline_ideal.txt boot_code/fibonacci.txt ${BOOT_CODE}
|
||||||
|
|
||||||
NO_ASM=1
|
NO_ASM=1
|
||||||
include common.mk
|
include common.mk
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm
|
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm fibonacci.asm
|
||||||
BINARIES=$(subst .asm,.txt,${SOURCE})
|
BINARIES=$(subst .asm,.txt,${SOURCE})
|
||||||
BUILD_FILES=${BINARIES}
|
BUILD_FILES=${BINARIES}
|
||||||
BUILD_FILES+=$(subst .asm,.memdump,${SOURCE})
|
BUILD_FILES+=$(subst .asm,.memdump,${SOURCE})
|
||||||
|
113
boot_code/fibonacci.asm
Normal file
113
boot_code/fibonacci.asm
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
INCLUDE dos_layer.asm
|
||||||
|
|
||||||
|
|
||||||
|
org 0x100
|
||||||
|
mov sp,#STACK
|
||||||
|
|
||||||
|
MOV AX,#0x1
|
||||||
|
MOV BX,#0x1
|
||||||
|
|
||||||
|
CALL PRINT_HEX
|
||||||
|
|
||||||
|
push bx
|
||||||
|
MAIN_LOOP:
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
CALL PRINT_HEX
|
||||||
|
|
||||||
|
push AX
|
||||||
|
ADD AX,BX
|
||||||
|
|
||||||
|
JNC MAIN_LOOP
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
MOV AH,#0x02
|
||||||
|
MOV DL,#0x0a
|
||||||
|
INT #0x21
|
||||||
|
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;Input AX
|
||||||
|
PRINT_HEX:
|
||||||
|
PUSH DX
|
||||||
|
|
||||||
|
TEST AH,#0xF0
|
||||||
|
jz NOT_FIRST_NIBBLE
|
||||||
|
MOV DL,AH
|
||||||
|
CALL PRINT_HIGH
|
||||||
|
JMP SKIP1
|
||||||
|
|
||||||
|
NOT_FIRST_NIBBLE:
|
||||||
|
TEST AH,#0x0F
|
||||||
|
jz NOT_SECOND_NIBBLE
|
||||||
|
SKIP1:
|
||||||
|
MOV DL,AH
|
||||||
|
CALL PRINT_LOW
|
||||||
|
JMP SKIP2
|
||||||
|
|
||||||
|
NOT_SECOND_NIBBLE:
|
||||||
|
TEST AL,#0xF0
|
||||||
|
jz NOT_THIRD_NIBBLE
|
||||||
|
SKIP2:
|
||||||
|
MOV DL,AL
|
||||||
|
CALL PRINT_HIGH
|
||||||
|
|
||||||
|
NOT_THIRD_NIBBLE:
|
||||||
|
MOV DL,AL
|
||||||
|
CALL PRINT_LOW
|
||||||
|
|
||||||
|
PUSH AX
|
||||||
|
MOV AH,#0x02
|
||||||
|
MOV DL,#0x20
|
||||||
|
INT #0x21
|
||||||
|
POP AX
|
||||||
|
|
||||||
|
POP DX
|
||||||
|
RET
|
||||||
|
|
||||||
|
PRINT_HIGH:
|
||||||
|
AND DL,#0xF0
|
||||||
|
TEST DL,#0x80
|
||||||
|
jz NOT1
|
||||||
|
OR DL,#0x08
|
||||||
|
NOT1:
|
||||||
|
TEST DL,#0x40
|
||||||
|
jz NOT2
|
||||||
|
OR DL,#0x04
|
||||||
|
NOT2:
|
||||||
|
TEST DL,#0x20
|
||||||
|
jz NOT3
|
||||||
|
OR DL,#0x02
|
||||||
|
NOT3:
|
||||||
|
TEST DL,#0x10
|
||||||
|
jz DONE
|
||||||
|
OR DL,#0x01
|
||||||
|
DONE:
|
||||||
|
|
||||||
|
PRINT_LOW:
|
||||||
|
PUSH AX
|
||||||
|
AND DL,#0x0F
|
||||||
|
CMP DL,#0x0A
|
||||||
|
JNS LETTERS
|
||||||
|
ADD DL,#0x30
|
||||||
|
MOV AH,#0x02
|
||||||
|
INT #0x21
|
||||||
|
POP AX
|
||||||
|
RET
|
||||||
|
|
||||||
|
LETTERS:
|
||||||
|
ADD DL,#0x37
|
||||||
|
MOV AH,#0x02
|
||||||
|
INT #0x21
|
||||||
|
POP AX
|
||||||
|
RET
|
||||||
|
|
||||||
|
.BLKB 200
|
||||||
|
STACK:
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
|
107
system/decoder.v
107
system/decoder.v
@ -108,6 +108,7 @@ wire [`UCODE_DATA_BITS-1:0] ucode_data;
|
|||||||
microcode ucode(seq_addr_input,ucode_data);
|
microcode ucode(seq_addr_input,ucode_data);
|
||||||
|
|
||||||
`define invalid_instruction next_state=`EXEC_WAIT;ERROR<=`ERR_UNIMPL_INSTRUCTION;IN_MOD=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION;
|
`define invalid_instruction next_state=`EXEC_WAIT;ERROR<=`ERR_UNIMPL_INSTRUCTION;IN_MOD=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION;
|
||||||
|
`define unimpl_addressing_mode next_state=`EXEC_WAIT;ERROR <= `ERR_UNIMPL_ADDRESSING_MODE;IN_MOD=3'b011;seq_addr_entry<=`UCODE_NO_INSTRUCTION;
|
||||||
|
|
||||||
|
|
||||||
//TODO: A possible optimisation for instruction with 8bit parameter and
|
//TODO: A possible optimisation for instruction with 8bit parameter and
|
||||||
@ -203,7 +204,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel1=2'b00;
|
in_alu_sel1=2'b00;
|
||||||
OUT_MOD=3'b100;
|
OUT_MOD=3'b100;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
ALU_OP=`ALU_OP_SUB;
|
ALU_OP=`ALU_OP_SUB_REVERSE;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
if(IN_MOD==3'b011)begin
|
if(IN_MOD==3'b011)begin
|
||||||
/*compare register with param*/
|
/*compare register with param*/
|
||||||
@ -379,7 +380,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu_sel2=2'b01;
|
in_alu_sel2=2'b01;
|
||||||
reg_read_port2_addr={Wbit,3'b000};
|
reg_read_port2_addr={Wbit,3'b000};
|
||||||
OUT_MOD=3'b100;
|
OUT_MOD=3'b100;
|
||||||
ALU_OP=`ALU_OP_SUB;
|
ALU_OP=`ALU_OP_SUB_REVERSE;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
if(Wbit==1)
|
if(Wbit==1)
|
||||||
next_state=`EXEC_DE_LOAD_16_PARAM;
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
@ -438,6 +439,13 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
else
|
else
|
||||||
next_state=`EXEC_WRITE_ENTRY;
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
end
|
end
|
||||||
|
3'b001: begin
|
||||||
|
/* Jump on (not) Carry */
|
||||||
|
if(FLAGS[0:0]==CIR[8:8])
|
||||||
|
next_state=`EXEC_NEXT_INSTRUCTION;
|
||||||
|
else
|
||||||
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction; /*We don't support that condition*/
|
`invalid_instruction; /*We don't support that condition*/
|
||||||
end
|
end
|
||||||
@ -517,7 +525,7 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
DEPENDS_ON_PREVIOUS<=0;
|
DEPENDS_ON_PREVIOUS<=0;
|
||||||
end
|
end
|
||||||
11'b1111_011?_000:begin
|
11'b1111_011?_000:begin
|
||||||
/* TEST - Bitwise AND affecting only flags */
|
/* TEST - Bitwise AND of immediate and registers/memmory 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;
|
||||||
Wbit=CIR[8:8];
|
Wbit=CIR[8:8];
|
||||||
@ -545,6 +553,28 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
DEPENDS_ON_PREVIOUS<=0;
|
DEPENDS_ON_PREVIOUS<=0;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
|
11'b1010_100?_???:begin
|
||||||
|
/* TEST - Bitwise AND of immediate and accumulator affecting only flags */
|
||||||
|
/* 1 0 1 0 1 0 0 W | DATA | DATA if W | */
|
||||||
|
opcode_size=0;
|
||||||
|
Wbit=CIR[8:8];
|
||||||
|
IN_MOD=3'b011;
|
||||||
|
RM=3'b000;
|
||||||
|
MEM_OR_IO=0;
|
||||||
|
if(Wbit==1)begin
|
||||||
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
|
end else begin
|
||||||
|
next_state=`EXEC_DE_LOAD_8_PARAM;
|
||||||
|
end
|
||||||
|
in_alu_sel1=2'b00; /* PARAM1 */
|
||||||
|
ALU_OP=`ALU_OP_AND;
|
||||||
|
in_alu_sel2=2'b01;
|
||||||
|
reg_read_port2_addr={Wbit,RM};
|
||||||
|
OUT_MOD=3'b100;/*NULL*/
|
||||||
|
`normal_instruction;
|
||||||
|
DEPENDS_ON_PREVIOUS<=0;
|
||||||
|
memio_address_select=0;
|
||||||
|
end
|
||||||
11'b0101_1???_???:begin
|
11'b0101_1???_???:begin
|
||||||
/* POP - REG=[SP]; SP+=2 */
|
/* POP - REG=[SP]; SP+=2 */
|
||||||
/* | 0 1 0 1 1 REG | */
|
/* | 0 1 0 1 1 REG | */
|
||||||
@ -651,6 +681,71 @@ always @( FLAGS or CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
DEPENDS_ON_PREVIOUS<=0;
|
DEPENDS_ON_PREVIOUS<=0;
|
||||||
memio_address_select=0;
|
memio_address_select=0;
|
||||||
end
|
end
|
||||||
|
11'b1000_000?_100,11'b1000_000?_001:begin
|
||||||
|
/* OR - Bitwise OR immediate and register/mem */
|
||||||
|
/* 1 0 0 0 0 0 0 W | MOD 0 0 1 R/M | < DISP-LO > | < DISP-HI > | DATA | DATA if W */
|
||||||
|
/* AND - Bitwise AND immediate and register/mem */
|
||||||
|
/* 1 0 0 0 0 0 0 W | MOD 1 0 0 R/M | < DISP-LO > | < DISP-HI > | DATA | DATA if W */
|
||||||
|
opcode_size=1;
|
||||||
|
Wbit=CIR[8:8];
|
||||||
|
IN_MOD={1'b0,CIR[7:6]};
|
||||||
|
RM={CIR[2:0]};
|
||||||
|
MEM_OR_IO=0;
|
||||||
|
if(Wbit==1)begin
|
||||||
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
|
end else begin
|
||||||
|
next_state=`EXEC_DE_LOAD_8_PARAM;
|
||||||
|
end
|
||||||
|
in_alu_sel1=2'b00; /* PARAM1 */
|
||||||
|
case(CIR[5:3])
|
||||||
|
3'b100: ALU_OP=`ALU_OP_AND;
|
||||||
|
3'b001: ALU_OP=`ALU_OP_OR;
|
||||||
|
default:begin end
|
||||||
|
endcase
|
||||||
|
case(IN_MOD)
|
||||||
|
3'b011:begin
|
||||||
|
in_alu_sel2=2'b01;
|
||||||
|
reg_read_port2_addr={Wbit,RM};
|
||||||
|
reg_write_addr={Wbit,RM};
|
||||||
|
end
|
||||||
|
default:begin
|
||||||
|
`unimpl_addressing_mode
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
OUT_MOD=IN_MOD;
|
||||||
|
DEPENDS_ON_PREVIOUS<=0;
|
||||||
|
memio_address_select=0;
|
||||||
|
`normal_instruction;
|
||||||
|
end
|
||||||
|
11'b0000_00??_???:begin
|
||||||
|
/* ADD - Reg/memory with register to either */
|
||||||
|
/* 0 0 0 0 0 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */
|
||||||
|
opcode_size=1;
|
||||||
|
Wbit=CIR[8:8];
|
||||||
|
Sbit=0;
|
||||||
|
OUT_MOD={1'b0,CIR[7:6]};
|
||||||
|
IN_MOD=3'b011;
|
||||||
|
RM=CIR[2:0];
|
||||||
|
in_alu_sel1=2'b01;//constantly register
|
||||||
|
reg_read_port1_addr={Wbit,CIR[5:3]};
|
||||||
|
if(IN_MOD==3'b011)begin
|
||||||
|
in_alu_sel2=2'b01;
|
||||||
|
reg_read_port2_addr={Wbit,RM};
|
||||||
|
reg_write_addr={Wbit,RM};
|
||||||
|
next_state=`EXEC_WRITE_ENTRY;
|
||||||
|
end else begin
|
||||||
|
in_alu_sel2=2'b00;
|
||||||
|
if(Wbit)
|
||||||
|
next_state=`EXEC_DE_LOAD_16_PARAM;
|
||||||
|
else
|
||||||
|
next_state=`EXEC_DE_LOAD_8_PARAM;
|
||||||
|
end
|
||||||
|
MEM_OR_IO=0;
|
||||||
|
memio_address_select=0;
|
||||||
|
ALU_OP=`ALU_OP_ADD;
|
||||||
|
DEPENDS_ON_PREVIOUS<=0;
|
||||||
|
`normal_instruction;
|
||||||
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
end
|
end
|
||||||
@ -732,6 +827,10 @@ module InstrSize ( input [10:0] IN, output reg [2:0] VERDICT );
|
|||||||
11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */
|
11'b1100_1101_??? : VERDICT <= 3'd2; /* INT - execute interrupt handler */
|
||||||
11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */
|
11'b1110_011?_??? : VERDICT <= 3'd2; /* OUT - write AL or AX to a defined output port */
|
||||||
11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */
|
11'b1100_1111_??? : VERDICT <= 3'd1; /* IRET - Return from interrupt */
|
||||||
|
11'b1000_000?_100 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* AND - Bitwise AND immediate and register/mem */
|
||||||
|
11'b1000_000?_001 : VERDICT <= 3'd3+{2'b0,IN[3:3]}; /* OR - Bitwise OR immediate and register/mem */
|
||||||
|
11'b1010_100?_??? : VERDICT <= 3'd2+{2'b0,IN[3:3]}; /* TEST - Bitwise AND affecting only flags */
|
||||||
|
11'b0000_00??_??? : VERDICT <= 3'd2; /* ADD - Reg/memory with register to either */
|
||||||
default:begin end
|
default:begin end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
@ -753,3 +852,5 @@ module Is1 ( input [7:0] IN, output reg VERDICT );
|
|||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
`undef unimpl_addressing_mode
|
||||||
|
@ -336,6 +336,6 @@ always @(posedge clock) begin
|
|||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
`undef unimpl_addressing_mode
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
`undef unimpl_addressing_mode
|
||||||
|
Loading…
Reference in New Issue
Block a user