The CPU works on real hardware for the first time! I added an adjustment for ram size, added control for a led and a test program for it. On the fpga board there is an actual led there that I used to verify functionality
This commit is contained in:
parent
30ffa1b00c
commit
01dcbfa7a1
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/pipeline_ideal.txt boot_code/fibonacci.txt boot_code/gnome_sort.txt boot_code/cache_fill_and_empty.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/gnome_sort.txt boot_code/cache_fill_and_empty.txt ${BOOT_CODE} boot_code/colored_led.txt
|
||||||
|
|
||||||
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 fibonacci.asm gnome_sort.asm cache_fill_and_empty.asm
|
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm fibonacci.asm gnome_sort.asm cache_fill_and_empty.asm colored_led.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})
|
||||||
|
32
boot_code/colored_led.asm
Normal file
32
boot_code/colored_led.asm
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.org 0x100
|
||||||
|
|
||||||
|
MAIN_LOOP:
|
||||||
|
MOV DL,#0xF0
|
||||||
|
DELAY11:
|
||||||
|
MOV AX,#0x0000
|
||||||
|
DELAY1:
|
||||||
|
INC AX
|
||||||
|
JNZ DELAY1
|
||||||
|
INC DL
|
||||||
|
JNZ DELAY11
|
||||||
|
|
||||||
|
MOV AL,#0x01
|
||||||
|
out byte #0xB0
|
||||||
|
|
||||||
|
MOV DL,#0xF0
|
||||||
|
DELAY21:
|
||||||
|
MOV AX,#0x0000
|
||||||
|
DELAY2:
|
||||||
|
INC AX
|
||||||
|
JNZ DELAY2
|
||||||
|
INC DL
|
||||||
|
JNZ DELAY21
|
||||||
|
MOV AL,#0x00
|
||||||
|
out byte #0xB0
|
||||||
|
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
||||||
|
|
||||||
|
.ORG 0xFFF0
|
||||||
|
MOV AX,#0x0100
|
||||||
|
JMP AX
|
@ -46,14 +46,14 @@ VERILATOR_OPTS += -x-assign fast --x-initial fast
|
|||||||
# COMPILING
|
# COMPILING
|
||||||
${SYSTEM_VVP} : ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES} ${EVENT_SIM_TESTBENCH}
|
${SYSTEM_VVP} : ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES} ${EVENT_SIM_TESTBENCH}
|
||||||
${QUIET_IVERILOG}
|
${QUIET_IVERILOG}
|
||||||
${Q}iverilog -g2012 -D CALCULATE_IPC -D OTUPUT_JSON_STATISTICS -o "$@" ${TOP_LEVEL_SOURCE} ${SOURCES} ${EVENT_SIM_TESTBENCH}
|
${Q}iverilog -g2012 -DBUILTIN_RAM=32768 -D CALCULATE_IPC -D OTUPUT_JSON_STATISTICS -o "$@" ${TOP_LEVEL_SOURCE} ${SOURCES} ${EVENT_SIM_TESTBENCH}
|
||||||
|
|
||||||
${VERILATOR_BIN}: ${VERILATOR_BIN}.mk
|
${VERILATOR_BIN}: ${VERILATOR_BIN}.mk
|
||||||
${Q}make ${MAKEOPTS} OPT_FAST="-O2 -march=native -mtune=native" -C obj_dir -f ../verilator_makefile Vsystem
|
${Q}make ${MAKEOPTS} OPT_FAST="-O2 -march=native -mtune=native" -C obj_dir -f ../verilator_makefile Vsystem
|
||||||
|
|
||||||
${VERILATOR_BIN}.mk: ${VERILATOR_TESTBENCH} ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES}
|
${VERILATOR_BIN}.mk: ${VERILATOR_TESTBENCH} ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES}
|
||||||
${QUIET_VERILATOR}
|
${QUIET_VERILATOR}
|
||||||
${Q}verilator -DCALCULATE_IPC -DOTUPUT_JSON_STATISTICS ${VERILATOR_OPTS} $^
|
${Q}verilator -DBUILTIN_RAM=32768 -UNOT_FULL -DCALCULATE_IPC -DOTUPUT_JSON_STATISTICS ${VERILATOR_OPTS} $^
|
||||||
|
|
||||||
# Synthesis and bitstream creation for ECP5
|
# Synthesis and bitstream creation for ECP5
|
||||||
ifeq "${ECP5_DEVICE}" "25F"
|
ifeq "${ECP5_DEVICE}" "25F"
|
||||||
@ -67,9 +67,10 @@ endif
|
|||||||
ECP5_TARGETS=synth_ecp5.json synth_ecp5_out.config synth_ecp5.bit synth_ecp5.dfu
|
ECP5_TARGETS=synth_ecp5.json synth_ecp5_out.config synth_ecp5.bit synth_ecp5.dfu
|
||||||
ECP5_TARGETS+=abc.history # created from yosys
|
ECP5_TARGETS+=abc.history # created from yosys
|
||||||
|
|
||||||
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${INCLUDES} boot_code.txt
|
#TODO: we are relying on yosys to trim the input program txt file and hope its enough for the whole program...
|
||||||
|
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${INCLUDES} ../boot_code/colored_led.txt
|
||||||
${QUIET_YOSYS}
|
${QUIET_YOSYS}
|
||||||
${Q} yosys -q -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ; synth_ecp5 -json $@"
|
${Q} yosys -q -D BUILTIN_RAM=512 -D NOT_FULL -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ; synth_ecp5 -json $@"
|
||||||
|
|
||||||
synth_ecp5_out.config:synth_ecp5.json
|
synth_ecp5_out.config:synth_ecp5.json
|
||||||
${QUIET_NEXTPNR}
|
${QUIET_NEXTPNR}
|
||||||
|
@ -46,6 +46,14 @@
|
|||||||
* . : ... */
|
* . : ... */
|
||||||
`define L1_CACHE_SIZE 4
|
`define L1_CACHE_SIZE 4
|
||||||
|
|
||||||
|
//// These are usually set at build time
|
||||||
|
//
|
||||||
|
// /* This is the "virtual" synthesised ram, so for example on an FPGA
|
||||||
|
// * This would be made inside the fabric of the fpga. */
|
||||||
|
// `define BUILTIN_RAM 512
|
||||||
|
// ////// ATTENTION: PLEASE IF BUILTIN_RAM DOESN'T COVER THE ENTIRE (CURRENTLY)
|
||||||
|
// // 16 BIT RANGE, I.E. ISN'T 32768, PLEASE SET THE FOLLOWING FLAG
|
||||||
|
// `define NOT_FULL
|
||||||
|
|
||||||
|
|
||||||
/********** Internal **********/
|
/********** Internal **********/
|
||||||
|
@ -36,7 +36,7 @@ wire [19:0] address_bus;
|
|||||||
wire [15:0] data_bus_read,data_bus_write;
|
wire [15:0] data_bus_read,data_bus_write;
|
||||||
wire rd,wr,BHE,IOMEM;
|
wire rd,wr,BHE,IOMEM;
|
||||||
system system(
|
system system(
|
||||||
/* MISC */ clk48,user_button
|
/* MISC */ clk48,reset
|
||||||
/* MEMORY / IO */ ,address_bus,data_bus_read,data_bus_write,BHE,rd,wr,IOMEM,HALT,ERROR
|
/* MEMORY / IO */ ,address_bus,data_bus_read,data_bus_write,BHE,rd,wr,IOMEM,HALT,ERROR
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -45,17 +45,56 @@ assign rgb_led0_r=rgb_led_color[0];
|
|||||||
assign rgb_led0_g=rgb_led_color[1];
|
assign rgb_led0_g=rgb_led_color[1];
|
||||||
assign rgb_led0_b=rgb_led_color[2];
|
assign rgb_led0_b=rgb_led_color[2];
|
||||||
|
|
||||||
always @(HALT or ERROR or user_button) begin
|
always @(negedge wr) begin
|
||||||
if (HALT==0) begin
|
if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
||||||
/* yellow */
|
if(data_bus_write[0:0]==1)
|
||||||
rgb_led_color<=3'b100;
|
rgb_led_color=3'b000;
|
||||||
end else if (ERROR != `ERROR_BITS'b0) begin
|
else
|
||||||
/* red */
|
rgb_led_color=3'b111;
|
||||||
rgb_led_color<=3'b110;
|
|
||||||
end else begin
|
|
||||||
/* green */
|
|
||||||
rgb_led_color<=3'b101;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// A bit useless since if the cpu ERORRS out or HALTS it will continue executing anyway
|
||||||
|
//always @(HALT or ERROR or user_button) begin
|
||||||
|
// if (HALT==1) begin
|
||||||
|
// /* yellow */
|
||||||
|
// rgb_led_color<=3'b100;
|
||||||
|
// end else if (ERROR != `ERROR_BITS'b0) begin
|
||||||
|
// /* red */
|
||||||
|
// rgb_led_color<=3'b110;
|
||||||
|
// end else begin
|
||||||
|
// /* green */
|
||||||
|
// rgb_led_color<=3'b101;
|
||||||
|
// end
|
||||||
|
//end
|
||||||
|
|
||||||
|
|
||||||
|
/*** RESET CIRCUIT ***/
|
||||||
|
|
||||||
|
reg [3:0] counter = 0;
|
||||||
|
|
||||||
|
always @(posedge clk48) begin
|
||||||
|
counter <= counter + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
reg reset=0;
|
||||||
|
reg [1:0] state=0;
|
||||||
|
|
||||||
|
always @(posedge counter[3]) begin
|
||||||
|
if(user_button==0)
|
||||||
|
state=2'b00;
|
||||||
|
case (state)
|
||||||
|
2'b00:begin
|
||||||
|
reset<=0;
|
||||||
|
state<=2'b01;
|
||||||
|
end
|
||||||
|
2'b01:begin
|
||||||
|
reset<=1;
|
||||||
|
state<=2'b10;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
module doublemem(input [19:0] address,output [15:0] cpu_read_data ,input [15:0] cpu_write_data,input rd,input wr,input BHE,input cs);
|
module doublemem(input [19:0] address,output [15:0] cpu_read_data ,input [15:0] cpu_write_data,input rd,input wr,input BHE,input cs);
|
||||||
/* verilator lint_on UNUSEDSIGNAL */
|
/* verilator lint_on UNUSEDSIGNAL */
|
||||||
|
|
||||||
reg [15:0] memory [0:32768];
|
reg [15:0] memory [0:`BUILTIN_RAM];
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
`ifndef YOSYS
|
`ifndef YOSYS
|
||||||
@ -31,16 +31,32 @@ initial begin
|
|||||||
$display("No boot code specified. Please add +BOOT_CODE=<path> to your vvp args");
|
$display("No boot code specified. Please add +BOOT_CODE=<path> to your vvp args");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
$readmemh(boot_code, memory,0,32767);
|
$readmemh(boot_code, memory,0,`BUILTIN_RAM-1);
|
||||||
`else
|
`else
|
||||||
//TODO: don't have it hard coded
|
//TODO: don't have it hard coded
|
||||||
$readmemh("boot_code.txt", memory,0,32767);
|
$readmemh("../boot_code/colored_led.txt", memory,0,`BUILTIN_RAM-1);
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`ifdef NOT_FULL
|
||||||
|
jump_mem[0]=16'hB800;
|
||||||
|
jump_mem[1]=16'h01ff;
|
||||||
|
jump_mem[2]=16'hE000;
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
|
`ifndef NOT_FULL
|
||||||
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? memory[address[16:1]][15:8] : 8'hz;
|
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? memory[address[16:1]][15:8] : 8'hz;
|
||||||
|
|
||||||
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? memory[address[16:1]][7:0] : 8'hz;
|
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? memory[address[16:1]][7:0] : 8'hz;
|
||||||
|
`else
|
||||||
|
|
||||||
|
reg[15:0] jump_mem [0:4'h7];
|
||||||
|
|
||||||
|
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? (address[15:4]==12'b111111111111 ? jump_mem[address[3:1]][15:8]:memory[address[16:1]][15:8]) : 8'hz;
|
||||||
|
|
||||||
|
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? (address[15:4]==12'b111111111111 ? jump_mem[address[3:1]][7:0]:memory[address[16:1]][7:0]) : 8'hz;
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
always @(negedge wr) begin
|
always @(negedge wr) begin
|
||||||
if( cs == 0 ) begin
|
if( cs == 0 ) begin
|
||||||
|
@ -104,8 +104,14 @@ end
|
|||||||
|
|
||||||
`ifndef SYNTHESIS
|
`ifndef SYNTHESIS
|
||||||
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 )begin
|
||||||
$write("%s" ,data_bus_write[15:8]);
|
$write("%s" ,data_bus_write[15:8]);
|
||||||
|
end else if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
||||||
|
if(data_bus_write[0:0]==1)
|
||||||
|
$display("\x1b[7mLed turned on\x1b[m\n");
|
||||||
|
else
|
||||||
|
$display("\x1b[7mLed turned off\x1b[m\n");
|
||||||
|
end
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user