Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
900610426d | |||
98e73af5da |
9
.gitignore
vendored
9
.gitignore
vendored
@ -5,12 +5,9 @@
|
|||||||
*.bf.asm
|
*.bf.asm
|
||||||
*.swp
|
*.swp
|
||||||
*.memdump
|
*.memdump
|
||||||
boot_code/brainfuck_interpreted.bin
|
*.json
|
||||||
boot_code/brainfuck_interpreted.txt
|
boot_code/*.bin
|
||||||
boot_code/brainfuck_mandelbrot.bin
|
boot_code/*.txt
|
||||||
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} boot_code/fibonacci.txt boot_code/gnome_sort.txt
|
||||||
|
|
||||||
NO_ASM=1
|
NO_ASM=1
|
||||||
include common.mk
|
include common.mk
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm
|
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm fibonacci.asm gnome_sort.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})
|
||||||
BUILD_FILES+=$(subst .asm,.fst,${SOURCE})
|
BUILD_FILES+=$(subst .asm,.fst,${SOURCE})
|
||||||
BUILD_FILES+=$(subst .asm,.bin,${SOURCE})
|
BUILD_FILES+=$(subst .asm,.bin,${SOURCE})
|
||||||
|
BUILD_FILES+=$(subst .asm,.json,${SOURCE})
|
||||||
|
|
||||||
all: ${BINARIES}
|
all: ${BINARIES}
|
||||||
|
|
||||||
@ -11,6 +12,9 @@ brainfuck_interpreted.bin: brainfuck_interpreter_v0.asm hello_9086.bf.asm dos_la
|
|||||||
brainfuck_compiled.bin: brainfuck_compiler_v1.asm hello_9086.bf.asm dos_layer.asm
|
brainfuck_compiled.bin: brainfuck_compiler_v1.asm hello_9086.bf.asm dos_layer.asm
|
||||||
brainfuck_mandelbrot.bin: brainfuck_compiler_v1.asm mandelbrot.bf.asm dos_layer.asm
|
brainfuck_mandelbrot.bin: brainfuck_compiler_v1.asm mandelbrot.bf.asm dos_layer.asm
|
||||||
|
|
||||||
|
fibonacci.bin: helpers.asm
|
||||||
|
gnome_sort.bin: helpers.asm
|
||||||
|
|
||||||
%.bf.asm:%.bf
|
%.bf.asm:%.bf
|
||||||
${Q}sed "s/[a-zA-Z\* ]//g;/^$$/d;s/^/.ASCII '/;s/\$$/'/" "$^" > $@
|
${Q}sed "s/[a-zA-Z\* ]//g;/^$$/d;s/^/.ASCII '/;s/\$$/'/" "$^" > $@
|
||||||
|
|
||||||
|
38
boot_code/fibonacci.asm
Normal file
38
boot_code/fibonacci.asm
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
INCLUDE dos_layer.asm
|
||||||
|
|
||||||
|
|
||||||
|
org 0x100
|
||||||
|
mov sp,#STACK
|
||||||
|
|
||||||
|
MOV AX,#0x1
|
||||||
|
MOV BX,#0x1
|
||||||
|
|
||||||
|
CALL PRINT_16_HEX
|
||||||
|
|
||||||
|
push bx
|
||||||
|
MAIN_LOOP:
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
CALL PRINT_16_HEX
|
||||||
|
|
||||||
|
push AX
|
||||||
|
ADD AX,BX
|
||||||
|
|
||||||
|
JNC MAIN_LOOP
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
MOV AH,#0x02
|
||||||
|
MOV DL,#0x0a
|
||||||
|
INT #0x21
|
||||||
|
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
.BLKB 200
|
||||||
|
STACK:
|
||||||
|
INCLUDE helpers.asm
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
|
54
boot_code/gnome_sort.asm
Normal file
54
boot_code/gnome_sort.asm
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
INCLUDE dos_layer.asm
|
||||||
|
|
||||||
|
.org 0x100
|
||||||
|
mov sp,#STACK
|
||||||
|
MOV SI,#DATA
|
||||||
|
|
||||||
|
GNOME_SORT:
|
||||||
|
CMP SI,#DATA+31
|
||||||
|
JZ GNOMED
|
||||||
|
MOV AX,[SI]
|
||||||
|
INC SI
|
||||||
|
CMP AH,AL
|
||||||
|
JAE GNOME_SORT
|
||||||
|
|
||||||
|
SWAP:
|
||||||
|
MOV BL,AL
|
||||||
|
MOV AL,AH
|
||||||
|
MOV AH,BL
|
||||||
|
DEC SI
|
||||||
|
MOV [SI],AX
|
||||||
|
CMP SI,#DATA
|
||||||
|
JZ GNOME_SORT
|
||||||
|
DEC SI
|
||||||
|
JMP GNOME_SORT
|
||||||
|
|
||||||
|
GNOMED:
|
||||||
|
MOV SI,#DATA
|
||||||
|
PRINT_LOOP:
|
||||||
|
MOV AL,[SI]
|
||||||
|
call PRINT_0_8_HEX
|
||||||
|
INC SI
|
||||||
|
CMP SI,#DATA+32
|
||||||
|
JNZ PRINT_LOOP
|
||||||
|
|
||||||
|
MOV AH,#0x02
|
||||||
|
MOV DL,#0x0a
|
||||||
|
INT #0x21
|
||||||
|
|
||||||
|
hlt
|
||||||
|
|
||||||
|
DATA: DB 0x51, 0x17, 0x37, 0x5d, 0x06, 0x3f, 0x51, 0x8b
|
||||||
|
DB 0xa5, 0x33, 0x54, 0xdf, 0xae, 0xee, 0x3a, 0x18
|
||||||
|
DB 0xe9, 0xdb, 0x1f, 0x21, 0x44, 0x4f, 0x99, 0x09
|
||||||
|
DB 0x2a, 0x23, 0x82, 0x4f, 0x52, 0xf1, 0xdc, 0x0b
|
||||||
|
|
||||||
|
.BLKB 200
|
||||||
|
STACK:
|
||||||
|
|
||||||
|
INCLUDE helpers.asm
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
|
93
boot_code/helpers.asm
Normal file
93
boot_code/helpers.asm
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
;Input AX
|
||||||
|
PRINT_16_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
|
||||||
|
|
||||||
|
PRINT_0_8_HEX:
|
||||||
|
MOV DL,AL
|
||||||
|
|
||||||
|
PUSH AX
|
||||||
|
CALL PRINT_HIGH
|
||||||
|
POP AX
|
||||||
|
|
||||||
|
MOV DL,AL
|
||||||
|
CALL PRINT_LOW
|
||||||
|
|
||||||
|
PUSH AX
|
||||||
|
MOV AH,#0x02
|
||||||
|
MOV DL,#0x20
|
||||||
|
INT #0x21
|
||||||
|
POP AX
|
||||||
|
|
||||||
|
RET
|
@ -57,6 +57,10 @@ ifeq "${SIM}" "ICARUS"
|
|||||||
%.run: %.txt ${SYSTEM_VVP} ${MICROCODE}
|
%.run: %.txt ${SYSTEM_VVP} ${MICROCODE}
|
||||||
${QUIET_VVP}
|
${QUIET_VVP}
|
||||||
${Q}vvp -i "${SYSTEM_VVP}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
${Q}vvp -i "${SYSTEM_VVP}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||||
|
|
||||||
|
%.json: %.txt ${SYSTEM_VVP} ${MICROCODE}
|
||||||
|
${QUIET_VVP}
|
||||||
|
${Q}vvp -i "${SYSTEM_VVP}" +STATS="$@" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||||
else ifeq "${SIM}" "VERILATOR"
|
else ifeq "${SIM}" "VERILATOR"
|
||||||
%.fst %.memdump: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
%.fst %.memdump: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
||||||
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
||||||
@ -64,6 +68,10 @@ else ifeq "${SIM}" "VERILATOR"
|
|||||||
${Q}grep -v '^//' "$(subst .txt,.memdumptxt,$<)" | xxd -ps -c 2 -r > "$(subst .txt,.memdump,$<)"
|
${Q}grep -v '^//' "$(subst .txt,.memdumptxt,$<)" | xxd -ps -c 2 -r > "$(subst .txt,.memdump,$<)"
|
||||||
${Q}rm "$(subst .txt,.memdumptxt,$<)"
|
${Q}rm "$(subst .txt,.memdumptxt,$<)"
|
||||||
|
|
||||||
|
%.json: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
||||||
|
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
||||||
|
${Q} ${NUMACTL} "${VERILATOR_BIN}" +STATS=$@ +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||||
|
|
||||||
%.run: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
%.run: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
||||||
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
||||||
${Q} ${NUMACTL} "${VERILATOR_BIN}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
${Q} ${NUMACTL} "${VERILATOR_BIN}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||||
|
@ -21,3 +21,12 @@
|
|||||||
//`define DEBUG_REG_WRITES
|
//`define DEBUG_REG_WRITES
|
||||||
//`define DEBUG_PC_ADDRESS
|
//`define DEBUG_PC_ADDRESS
|
||||||
//`define DEBUG_MEMORY_WRITES
|
//`define DEBUG_MEMORY_WRITES
|
||||||
|
|
||||||
|
`define CALCULATE_IPC
|
||||||
|
`define OUTPUT_JSON_STATISTICS
|
||||||
|
|
||||||
|
/********** Internal **********/
|
||||||
|
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
`define CALCULATE_IPC
|
||||||
|
`endif
|
||||||
|
125
system/decoder.v
125
system/decoder.v
@ -184,19 +184,22 @@ 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;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
ALU_1OP=`ALU_OP_SUB;
|
ALU_1OP=`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*/
|
||||||
in_alu1_sel2=2'b01;
|
in_alu1_sel2=2'b01;
|
||||||
reg_read_port2_addr={Wbit,RM};
|
reg_read_port2_addr={Wbit,RM};
|
||||||
next_state=`PROC_DE_LOAD_8_PARAM;
|
|
||||||
end else begin
|
end else begin
|
||||||
/*compare register indirect access
|
/*compare register indirect access
|
||||||
* with param */
|
* with param */
|
||||||
in_alu1_sel2=2'b00;
|
in_alu1_sel2=2'b00;
|
||||||
next_state=`PROC_DE_LOAD_16_PARAM; /*will then call MEMIO_READ*/
|
/*will call MEMIO_READ after EXEC_DE_LOAD..*/
|
||||||
end
|
end
|
||||||
|
if (Wbit)
|
||||||
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
|
else
|
||||||
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
end
|
end
|
||||||
11'b1011_0???_??? : begin
|
11'b1011_0???_??? : begin
|
||||||
@ -364,7 +367,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
in_alu1_sel2=2'b01;
|
in_alu1_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_1OP=`ALU_OP_SUB;
|
ALU_1OP=`ALU_OP_SUB_REVERSE;
|
||||||
MEM_OR_IO=0;
|
MEM_OR_IO=0;
|
||||||
if(Wbit==1)
|
if(Wbit==1)
|
||||||
next_state=`PROC_DE_LOAD_16_PARAM;
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
@ -423,6 +426,13 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
else
|
else
|
||||||
next_state=`PROC_EX_STATE_ENTRY;
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
end
|
end
|
||||||
|
3'b001: begin
|
||||||
|
/* Jump on (not) Carry */
|
||||||
|
if(FLAGS[0:0]==CIR[8:8])
|
||||||
|
next_state=`PROC_IF_STATE_ENTRY;
|
||||||
|
else
|
||||||
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction; /*We don't support that condition*/
|
`invalid_instruction; /*We don't support that condition*/
|
||||||
end
|
end
|
||||||
@ -526,6 +536,29 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
`normal_instruction;
|
`normal_instruction;
|
||||||
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
|
||||||
|
instruction_size=3;
|
||||||
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
|
end else begin
|
||||||
|
instruction_size=2;
|
||||||
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
|
end
|
||||||
|
in_alu1_sel1=2'b00; /* PARAM1 */
|
||||||
|
ALU_1OP=`ALU_OP_AND;
|
||||||
|
in_alu1_sel2=2'b01;
|
||||||
|
reg_read_port2_addr={Wbit,RM};
|
||||||
|
OUT_MOD=3'b100;/*NULL*/
|
||||||
|
`normal_instruction;
|
||||||
|
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 | */
|
||||||
@ -629,6 +662,90 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
|
|||||||
seq_addr_entry<=`UCODE_RET_ENTRY;
|
seq_addr_entry<=`UCODE_RET_ENTRY;
|
||||||
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
|
||||||
|
instruction_size=4;
|
||||||
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
|
end else begin
|
||||||
|
instruction_size=3;
|
||||||
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
|
end
|
||||||
|
in_alu1_sel1=2'b00; /* PARAM1 */
|
||||||
|
case(CIR[5:3])
|
||||||
|
3'b100: ALU_1OP=`ALU_OP_AND;
|
||||||
|
3'b001: ALU_1OP=`ALU_OP_OR;
|
||||||
|
default:begin end
|
||||||
|
endcase
|
||||||
|
case(IN_MOD)
|
||||||
|
3'b011:begin
|
||||||
|
in_alu1_sel2=2'b01;
|
||||||
|
reg_read_port2_addr={Wbit,RM};
|
||||||
|
reg_write_addr={Wbit,RM};
|
||||||
|
`normal_instruction;
|
||||||
|
end
|
||||||
|
default:begin
|
||||||
|
`invalid_instruction;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
OUT_MOD=IN_MOD;
|
||||||
|
memio_address_select=0;
|
||||||
|
end
|
||||||
|
11'b0000_00??_???,11'b0010_10??_???,11'b0011_10??_???:begin
|
||||||
|
/* CMP - Compare Register/memory and register */
|
||||||
|
/* 0 0 1 1 1 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */
|
||||||
|
/* SUB - Reg/memory with register to either */
|
||||||
|
/* 0 0 1 0 1 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */
|
||||||
|
/* ADD - Reg/memory with register to either */
|
||||||
|
/* 0 0 0 0 0 0 D W | MOD REG R/M | < DISP LO > | < DISP HI > | */
|
||||||
|
instruction_size=2;
|
||||||
|
opcode_size=1;
|
||||||
|
Wbit=CIR[8:8];
|
||||||
|
Sbit=0;
|
||||||
|
IN_MOD=3'b011;
|
||||||
|
RM=CIR[2:0];
|
||||||
|
in_alu1_sel1=2'b01;//constantly register
|
||||||
|
reg_read_port1_addr={Wbit,CIR[5:3]};
|
||||||
|
if(IN_MOD==3'b011)begin
|
||||||
|
in_alu1_sel2=2'b01;
|
||||||
|
reg_read_port2_addr={Wbit,RM};
|
||||||
|
reg_write_addr={Wbit,RM};
|
||||||
|
next_state=`PROC_EX_STATE_ENTRY;
|
||||||
|
end else begin
|
||||||
|
in_alu1_sel2=2'b00;
|
||||||
|
if(Wbit)
|
||||||
|
next_state=`PROC_DE_LOAD_16_PARAM;
|
||||||
|
else
|
||||||
|
next_state=`PROC_DE_LOAD_8_PARAM;
|
||||||
|
end
|
||||||
|
MEM_OR_IO=0;
|
||||||
|
memio_address_select=0;
|
||||||
|
case (CIR[13:10])
|
||||||
|
4'b0000: ALU_1OP=`ALU_OP_ADD;
|
||||||
|
4'b1010: ALU_1OP=`ALU_OP_SUB;
|
||||||
|
4'b1110: ALU_1OP=`ALU_OP_SUB_REVERSE;
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
case (CIR[13:10])
|
||||||
|
4'b0000: OUT_MOD={1'b0,CIR[7:6]};
|
||||||
|
4'b1010: OUT_MOD={1'b0,CIR[7:6]};
|
||||||
|
4'b1110: OUT_MOD=3'b100; /* NULL */
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
if(CIR[9:9]==1'b0) begin
|
||||||
|
`normal_instruction;
|
||||||
|
end else begin
|
||||||
|
`invalid_instruction
|
||||||
|
end
|
||||||
|
end
|
||||||
default:begin
|
default:begin
|
||||||
`invalid_instruction
|
`invalid_instruction
|
||||||
end
|
end
|
||||||
|
@ -29,7 +29,17 @@
|
|||||||
//read: active low
|
//read: active low
|
||||||
//reset: 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);
|
module processor (
|
||||||
|
/* MISC */ input clock, input reset, output reg HALT,output reg ERROR
|
||||||
|
/* MEMORY / IO */ ,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
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
/* STATISTICS */ ,output reg new_instruction
|
||||||
|
`endif
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
/* */ , output reg jump_debug
|
||||||
|
`endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/*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;
|
||||||
@ -198,6 +208,12 @@ always @(posedge clock) begin
|
|||||||
reg_write_we <= 1;
|
reg_write_we <= 1;
|
||||||
instruction_size_init <= 1;
|
instruction_size_init <= 1;
|
||||||
state <= `PROC_IF_STATE_ENTRY;
|
state <= `PROC_IF_STATE_ENTRY;
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
new_instruction <= 0;
|
||||||
|
`endif
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
jump_debug <= 0;
|
||||||
|
`endif
|
||||||
end
|
end
|
||||||
`PROC_HALT_STATE:begin
|
`PROC_HALT_STATE:begin
|
||||||
end
|
end
|
||||||
@ -210,6 +226,9 @@ always @(posedge clock) begin
|
|||||||
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;
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
jump_debug <= 0;
|
||||||
|
`endif
|
||||||
end
|
end
|
||||||
`PROC_IF_WRITE_CIR:begin
|
`PROC_IF_WRITE_CIR:begin
|
||||||
`ifdef DEBUG_PC_ADDRESS
|
`ifdef DEBUG_PC_ADDRESS
|
||||||
@ -224,6 +243,9 @@ always @(posedge clock) begin
|
|||||||
$display("Fetched instruction at %0x",ProgCount - 0);
|
$display("Fetched instruction at %0x",ProgCount - 0);
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
new_instruction <= !new_instruction;
|
||||||
|
`endif
|
||||||
/*I built the entire decode stage with CIR
|
/*I built the entire decode stage with CIR
|
||||||
* being big endian so just convert it here*/
|
* being big endian so just convert it here*/
|
||||||
|
|
||||||
@ -523,6 +545,9 @@ always @(posedge clock) begin
|
|||||||
state <= `PROC_NEXT_MICROCODE;
|
state <= `PROC_NEXT_MICROCODE;
|
||||||
end
|
end
|
||||||
3'b101:begin /* Program Counter*/
|
3'b101:begin /* Program Counter*/
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
jump_debug <= 1;
|
||||||
|
`endif
|
||||||
ProgCount <= ALU_1O[15:0];
|
ProgCount <= ALU_1O[15:0];
|
||||||
instruction_size_init <= 1;
|
instruction_size_init <= 1;
|
||||||
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
||||||
@ -609,6 +634,9 @@ always @(posedge clock) begin
|
|||||||
state <= `PROC_NEXT_MICROCODE;
|
state <= `PROC_NEXT_MICROCODE;
|
||||||
end
|
end
|
||||||
`PROC_NEXT_MICROCODE:begin
|
`PROC_NEXT_MICROCODE:begin
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
jump_debug <= 0;
|
||||||
|
`endif
|
||||||
read <= 0;
|
read <= 0;
|
||||||
write <= 1; // maybe we are coming from MEMIO_WRITE
|
write <= 1; // maybe we are coming from MEMIO_WRITE
|
||||||
BHE <= 0;
|
BHE <= 0;
|
||||||
|
@ -18,31 +18,78 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
||||||
|
`include "config.v"
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
wire new_instruction;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
wire jump;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
processor p(
|
||||||
|
/* MISC */ clock,reset,HALT,ERROR
|
||||||
|
/* MEMORY / IO */ ,address_bus,data_bus,rd,wr,BHE,IOMEM
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
/* STATISTICS */ ,new_instruction
|
||||||
|
`endif
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
/* */ , jump
|
||||||
|
`endif
|
||||||
|
);
|
||||||
|
|
||||||
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
||||||
|
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
string stats_name;
|
||||||
|
integer json_file_descriptor;
|
||||||
|
`endif
|
||||||
string waveform_name;
|
string waveform_name;
|
||||||
initial begin
|
initial begin
|
||||||
if($value$plusargs("WAVEFORM=%s",waveform_name))begin
|
if($value$plusargs("WAVEFORM=%s",waveform_name))begin
|
||||||
$dumpfile(waveform_name);
|
$dumpfile(waveform_name);
|
||||||
$dumpvars(0,p);
|
$dumpvars(0,p);
|
||||||
end
|
end
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
if($value$plusargs("STATS=%s",stats_name))begin
|
||||||
|
json_file_descriptor=$fopen(stats_name,"w");
|
||||||
|
$fdisplay(json_file_descriptor,"{\n\"L1_size\":0,\n\"Cycles\":[");
|
||||||
|
first_json_cycle = 1;
|
||||||
|
end else
|
||||||
|
json_file_descriptor=0;
|
||||||
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
reg first_json_cycle;
|
||||||
|
always @(negedge clock)begin
|
||||||
|
if(HALT==0 && json_file_descriptor!=0)begin
|
||||||
|
$fdisplay(json_file_descriptor,"%s{\"C\":%0d,\"JMP\":%0d}",first_json_cycle?"":",",cycles,jump);
|
||||||
|
first_json_cycle <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
always @(negedge wr) begin
|
always @(negedge wr) begin
|
||||||
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )
|
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )
|
||||||
$write("%s" ,data_bus[15:8]);
|
$write("%s" ,data_bus[15:8]);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
reg [128:0] instruction_count;
|
||||||
|
always @(new_instruction) begin
|
||||||
|
instruction_count<=instruction_count+1;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
reg [1:0] finish;
|
reg [1:0] finish;
|
||||||
|
|
||||||
string memdump_name;
|
string memdump_name;
|
||||||
always @(posedge HALT) begin
|
always @(posedge HALT) begin
|
||||||
$display("Processor halted.\nCycles run for: %d",cycles-1);
|
|
||||||
if($value$plusargs("MEMDUMP=%s",memdump_name))begin
|
if($value$plusargs("MEMDUMP=%s",memdump_name))begin
|
||||||
$writememh(memdump_name, sysmem.memory,0,32767);
|
$writememh(memdump_name, sysmem.memory,0,32767);
|
||||||
end
|
end
|
||||||
@ -53,7 +100,17 @@ always @(posedge clock) begin
|
|||||||
/* Allow some clock cycles for the waveform*/
|
/* Allow some clock cycles for the waveform*/
|
||||||
case(finish)
|
case(finish)
|
||||||
2'd0: begin end
|
2'd0: begin end
|
||||||
2'd1: finish <= 2;
|
2'd1: begin
|
||||||
|
finish <= 2;
|
||||||
|
$display("\x1b[7mProcessor halted.\nCycles run for : %0d\x1b[m",cycles);
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
$display("\x1b[7mInstr. per cycle : %f\x1b[m", $itor(instruction_count) / $itor(cycles) );
|
||||||
|
`endif
|
||||||
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
|
if(json_file_descriptor!=0)
|
||||||
|
$fdisplay(json_file_descriptor,"],\n\"Total Cycles\":%0d,\n\"Instructions run\":%0d\n}",cycles,instruction_count);
|
||||||
|
`endif
|
||||||
|
end
|
||||||
2'd2: finish <= 3;
|
2'd2: finish <= 3;
|
||||||
2'd3: $finish;
|
2'd3: $finish;
|
||||||
endcase
|
endcase
|
||||||
@ -67,13 +124,17 @@ always @(posedge ERROR) begin
|
|||||||
finish<=2'd1;
|
finish<=2'd1;
|
||||||
end
|
end
|
||||||
|
|
||||||
integer cycles=0;
|
reg [128:0] cycles=0;
|
||||||
|
|
||||||
always @(posedge clock)begin
|
always @(negedge clock)begin
|
||||||
if(reset==1)
|
if(reset==1)
|
||||||
cycles<=cycles+1;
|
cycles<=cycles+1;
|
||||||
else
|
else begin
|
||||||
cycles<=0;
|
cycles<=0;
|
||||||
|
`ifdef CALCULATE_IPC
|
||||||
|
instruction_count <= 0;
|
||||||
|
`endif
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,13 +46,28 @@ clock_gen #(.FREQ(1000)) u1(clk_enable, clock);
|
|||||||
string memdump_name;
|
string memdump_name;
|
||||||
initial begin
|
initial begin
|
||||||
clk_enable = 1;
|
clk_enable = 1;
|
||||||
|
do_reset = 0;
|
||||||
|
reset<=1;
|
||||||
|
end
|
||||||
|
|
||||||
reset = 1;
|
reg [1:0]do_reset;
|
||||||
#(`CPU_SPEED*2)
|
|
||||||
reset = 0;
|
always @(posedge clock) begin
|
||||||
#($random%1000)
|
case(do_reset)
|
||||||
#(`CPU_SPEED)
|
2'd0:begin
|
||||||
reset = 1;
|
do_reset<=1;
|
||||||
|
end
|
||||||
|
2'd1:begin
|
||||||
|
do_reset<=2;
|
||||||
|
reset <= 0;
|
||||||
|
end
|
||||||
|
2'd2:begin
|
||||||
|
do_reset<=3;
|
||||||
|
reset <= 1;
|
||||||
|
end
|
||||||
|
2'd3:begin
|
||||||
|
end
|
||||||
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user