Wrote a more complete testbench for verilator, switched from lx2 to fst and fixed cpu clock frequency calculation

This commit is contained in:
(Tim) Efthimis Kritikos 2023-03-05 00:10:55 +00:00
parent 5705b8e8a5
commit 99cbc49e95
8 changed files with 112 additions and 73 deletions

3
.gitignore vendored
View File

@ -1,11 +1,10 @@
*.vvp *.vvp
*.vpi *.vpi
*.lx2 *.fst
*.o *.o
*.bf.asm *.bf.asm
*.swp *.swp
*.memdump *.memdump
*.lxt # Not sure when those crop up
boot_code/brainfuck_interpreted.bin boot_code/brainfuck_interpreted.bin
boot_code/brainfuck_interpreted.txt boot_code/brainfuck_interpreted.txt
boot_code/brainfuck_mandelbrot.bin boot_code/brainfuck_mandelbrot.bin

View File

@ -2,7 +2,7 @@ SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.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,.lx2,${SOURCE}) BUILD_FILES+=$(subst .asm,.fst,${SOURCE})
BUILD_FILES+=$(subst .asm,.bin,${SOURCE}) BUILD_FILES+=$(subst .asm,.bin,${SOURCE})
all: ${BINARIES} all: ${BINARIES}
@ -19,4 +19,4 @@ include ../common.mk
clean: clean:
$(call QUIET_CLEAN,boot_code) $(call QUIET_CLEAN,boot_code)
${Q}rm -f $(BUILD_FILES) *lxt *.bf.asm ${Q}rm -f $(BUILD_FILES) *.bf.asm

View File

@ -5,10 +5,11 @@ QUIET=1
# 2=normal make output # 2=normal make output
SIM=VERILATOR SIM=VERILATOR
#SIM=ICARUS
# SIM: VERILATOR: use Verilator # SIM: VERILATOR: use Verilator
# ICARUS: use Icarus Verilog # ICARUS: use Icarus Verilog
NUMACTL=#numactl -m 0 -C 0,1 --
ifeq "${QUIET}" "1" ifeq "${QUIET}" "1"
QUIET_AS = @echo ' AS '$@; QUIET_AS = @echo ' AS '$@;
@ -46,9 +47,9 @@ endif
# Running simulation # Running simulation
ifeq "${SIM}" "ICARUS" ifeq "${SIM}" "ICARUS"
%.lx2 %.memdump: %.txt ${SYSTEM_VVP} ${MICROCODE} %.fst %.memdump: %.txt ${SYSTEM_VVP} ${MICROCODE}
${QUIET_VVP} ${QUIET_VVP}
${Q}vvp "${SYSTEM_VVP}" -lxt2 +BOOT_CODE="$<" +WAVEFORM="$(subst .txt,.lx2,$<)" +MEMDUMP="$(subst .txt,.memdumptxt,$<)" +MICROCODE="${MICROCODE}" ${Q}vvp "${SYSTEM_VVP}" -fst +BOOT_CODE="$<" +WAVEFORM="$(subst .txt,.fst,$<)" +MEMDUMP="$(subst .txt,.memdumptxt,$<)" +MICROCODE="${MICROCODE}"
${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,$<)"
@ -56,20 +57,20 @@ ifeq "${SIM}" "ICARUS"
${QUIET_VVP} ${QUIET_VVP}
${Q}vvp -i "${SYSTEM_VVP}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}" ${Q}vvp -i "${SYSTEM_VVP}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
else ifeq "${SIM}" "VERILATOR" else ifeq "${SIM}" "VERILATOR"
%.lx2 %.memdump: %.txt ${VERILATOR_BIN} ${MICROCODE} %.fst %.memdump: %.txt ${VERILATOR_BIN} ${MICROCODE}
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<) $(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
${Q}"${VERILATOR_BIN}" +BOOT_CODE="$<" +WAVEFORM="$(subst .txt,.lx2,$<)" +MEMDUMP="$(subst .txt,.memdumptxt,$<)" +MICROCODE="${MICROCODE}" ${Q}"${VERILATOR_BIN}" +BOOT_CODE="$<" +WAVEFORM="$(subst .txt,.fst,$<)" +MEMDUMP="$(subst .txt,.memdumptxt,$<)" +MICROCODE="${MICROCODE}"
${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,$<)"
%.run: %.txt ${VERILATOR_BIN} ${MICROCODE} %.run: %.txt ${VERILATOR_BIN} ${MICROCODE}
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<) $(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
${Q}numactl -m 0 -C 17,18 -- "${VERILATOR_BIN}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}" ${Q} ${NUMACTL} "${VERILATOR_BIN}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
endif endif
%.disas: %.bin %.disas: %.bin
objdump -D -b binary -m i8086 $^ | less objdump -D -b binary -m i8086 $^ | less
# Tools # Tools
%.wave : %.lx2 %.wave : %.fst
gtkwave "$<" "${GTKWSAVE}" gtkwave "$<" "${GTKWSAVE}"

View File

@ -1,37 +1,42 @@
[*] [*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI [*] GTKWave Analyzer v3.3.111 (w)1999-2020 BSI
[*] Tue Feb 21 04:41:50 2023 [*] Sat Mar 4 23:56:38 2023
[*] [*]
[dumpfile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/boot_code/brainfuck_compiled.lx2" [dumpfile] "/home/user/9086/boot_code/brainfuck_compiled.fst"
[dumpfile_mtime] "Tue Feb 21 04:40:18 2023" [dumpfile_mtime] "Sat Mar 4 23:55:57 2023"
[dumpfile_size] 21374 [dumpfile_size] 464968
[savefile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/gtkwave_savefile.gtkw" [savefile] "/home/user/9086/gtkwave_savefile.gtkw"
[timestart] 513190000 [timestart] 500000000
[size] 1342 1059 [size] 1332 1017
[pos] -1 -1 [pos] -1 -1
*-23.795050 802940000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 *-37.895050 40500000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb. [treeopen] TOP.
[treeopen] tb.p. [treeopen] TOP.system.
[sst_width] 221 [sst_width] 221
[signals_width] 293 [signals_width] 293
[sst_expanded] 1 [sst_expanded] 1
[sst_vpaned_height] 312 [sst_vpaned_height] 312
@28 @28
tb.p.clock[0] TOP.system.clock
tb.p.reset[0] TOP.system.reset
tb.p.state[5:0] TOP.system.p.state[5:0]
@23
tb.p.ucode_seq_addr[4:0]
@22 @22
tb.p.external_address_bus[19:0] TOP.system.p.ucode_seq_addr[3:0]
tb.p.external_data_bus[15:0] TOP.system.address_bus[19:0]
tb.p.CIR[15:0] TOP.system.data_bus[15:0]
tb.p.PARAM1[15:0] TOP.system.p.CIR[15:0]
tb.p.PARAM2[15:0] TOP.system.p.PARAM1[15:0]
TOP.system.p.PARAM2[15:0]
@28 @28
tb.p.read[0] TOP.system.p.read
tb.p.write[0] TOP.system.p.write
tb.p.ERROR[0] @22
tb.p.SIMPLE_MICRO[0] TOP.system.p.ALU_1A[15:0]
TOP.system.p.ALU_1B[15:0]
TOP.system.p.ALU_1O[15:0]
@28
TOP.system.p.ERROR
@29
TOP.system.p.HALT
[pattern_trace] 1 [pattern_trace] 1
[pattern_trace] 0 [pattern_trace] 0

View File

@ -36,9 +36,9 @@ ${SYSTEM_VVP} : ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES} ${EVENT_SIM_TESTBENCH
${VERILATOR_BIN}: ${VERILATOR_TESTBENCH} ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES} ${VERILATOR_BIN}: ${VERILATOR_TESTBENCH} ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES}
${QUIET_VERILATOR} ${QUIET_VERILATOR}
${Q}verilator --cc --exe --build -j 0 $^ -Wall --Wno-DECLFILENAME -Wno-SYNCASYNCNET -Wno-MULTIDRIVEN 2>&1 --threads 1 --autoflush >/dev/null #TODO: remove the silencing and make the generated Makefiles print quietly as well ${Q}verilator --trace-fst --cc --exe --build -j 0 $^ -Wall --Wno-DECLFILENAME -Wno-SYNCASYNCNET -Wno-MULTIDRIVEN 2>&1 --threads 1 --autoflush >/dev/null #TODO: remove the silencing and make the generated Makefiles print quietly as well
.PHONY: clean .PHONY: clean
clean: clean:
$(call QUIET_CLEAN,system) $(call QUIET_CLEAN,system)
${Q}rm -rf ${SYSTEM_VVP} *.lx2 boot_code.txt boot_code.bin *memdump *memdumptxt obj_dir ${Q}rm -rf ${SYSTEM_VVP} *.fst boot_code.txt boot_code.bin *memdump *memdumptxt obj_dir

View File

@ -1,17 +1,55 @@
`define CPU_SPEED 1000 `timescale 1ns/1ps
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); processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM); doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
string waveform_name;
initial begin
if($value$plusargs("WAVEFORM=%s",waveform_name))begin
$dumpfile(waveform_name);
$dumpvars(0,p);
end
end
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); $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
// #(`CPU_SPEED) //Just for the waveform finish<=2'd1;
$finish;
end end
always @(posedge clock) begin
/* Allow some clock cycles for the waveform*/
case(finish)
2'd0: begin end
2'd1: finish <= 2;
2'd2: finish <= 3;
2'd3: $finish;
endcase
end
always @(posedge ERROR) begin
$display("PROCESSOR RUN INTO AN ERROR.\nCycles run for: %d",cycles-1);
if($value$plusargs("MEMDUMP=%s",memdump_name))begin
$writememh(memdump_name, system.sysmem.memory,0,32767);
end
finish<=2'd1;
end
integer cycles=0;
always @(posedge clock)begin
if(reset==1)
cycles<=cycles+1;
else
cycles<=0;
end
endmodule endmodule

View File

@ -3,11 +3,19 @@
#include "stdio.h" #include "stdio.h"
Vsystem *system_state; Vsystem *system_state;
VerilatedContext* contextp;
/*In hz */
#define CPU_SPEED 1000
#define timeinc CPU_SPEED*1000000/2
void tick() { void tick() {
system_state->clock = 1; system_state->clock = 1;
contextp->timeInc(timeinc);
system_state->eval(); system_state->eval();
system_state->clock = 0; system_state->clock = 0;
contextp->timeInc(timeinc);
system_state->eval(); system_state->eval();
//printf("tick() %04x\n",system_state->address_bus); //printf("tick() %04x\n",system_state->address_bus);
//trace->dump(timestamp); //trace->dump(timestamp);
@ -15,17 +23,31 @@ void tick() {
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
VerilatedContext* contextp = new VerilatedContext; contextp = new VerilatedContext;
// Set debug level, 0 is off, 9 is highest presently used
// May be overridden by commandArgs argument parsing
contextp->debug(0);
// Verilator must compute traced signals
contextp->traceEverOn(true);
contextp->commandArgs(argc, argv); contextp->commandArgs(argc, argv);
system_state = new Vsystem{contextp}; system_state = new Vsystem{contextp};
system_state->reset=1; system_state->reset=1;
tick(); tick();
system_state->reset=0; system_state->reset=0;
tick(); tick();
system_state->reset=1; system_state->reset=1;
// Simulate until $finish
while(!contextp->gotFinish()){ while(!contextp->gotFinish()){
tick(); tick();
} }
system_state->final();
delete system_state; delete system_state;
delete contextp; delete contextp;
return 0; return 0;

View File

@ -17,7 +17,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
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 /*In hz */
`define CPU_SPEED 1000
module tb; module tb;
wire clock; wire clock;
@ -40,19 +41,10 @@ system system( .clock(clock),
.IOMEM(IOMEM) .IOMEM(IOMEM)
); );
`define CPU_SPEED 1000
clock_gen #(.FREQ(1000)) u1(clk_enable, clock); clock_gen #(.FREQ(1000)) u1(clk_enable, clock);
integer cycles=0;
string memdump_name; string memdump_name;
initial begin initial begin
string waveform_name;
if($value$plusargs("WAVEFORM=%s",waveform_name))begin
$dumpfile(waveform_name);
$dumpvars(0,system);
end
clk_enable = 1; clk_enable = 1;
reset = 1; reset = 1;
@ -63,24 +55,6 @@ initial begin
reset = 1; reset = 1;
end end
always @(posedge ERROR) begin
clk_enable <= 0;
$display("PROCESSOR RUN INTO AN ERROR.\nCycles run for: %d",cycles);
if($value$plusargs("MEMDUMP=%s",memdump_name))begin
$writememh(memdump_name, system.sysmem.memory,0,32767);
end
#(`CPU_SPEED) //Just for the waveform
$finish;
end
always @(posedge clock)begin
if(reset==1)
cycles=cycles+1;
else
cycles=0;
end
endmodule endmodule
@ -91,7 +65,7 @@ parameter FREQ = 1000; // in HZ
parameter PHASE = 0; // in degrees parameter PHASE = 0; // in degrees
parameter DUTY = 50; // in percentage parameter DUTY = 50; // in percentage
real clk_pd = 1.0/FREQ * 1000000; // convert to ms real clk_pd = 1.0/FREQ * 1000000000; // convert to ms
real clk_on = DUTY/100.0 * clk_pd; real clk_on = DUTY/100.0 * clk_pd;
real clk_off = (100.0 - DUTY)/100.0 * clk_pd; real clk_off = (100.0 - DUTY)/100.0 * clk_pd;
real quarter = clk_pd/4; real quarter = clk_pd/4;