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:
(Tim) Efthimis Kritikos 2023-11-06 08:12:58 +00:00
parent 30ffa1b00c
commit 01dcbfa7a1
8 changed files with 123 additions and 21 deletions

View File

@ -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

View File

@ -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
View 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

View File

@ -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}

View File

@ -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 **********/

View File

@ -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

View File

@ -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

View File

@ -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