From 45160b50a96b6eb067d73703a99bf55317e7c501 Mon Sep 17 00:00:00 2001 From: Nam Tran Date: Fri, 23 Oct 2020 14:42:07 -0500 Subject: [PATCH] add tut3 folder, shift register code works --- .gitignore | 6 ++-- fsm/Makefile | 56 ++++++++++++++++++++++++++++++++++++++ fsm/constraints/iceFUN.pcf | 12 ++++++++ fsm/constraints/timing.py | 1 + fsm/rtl/clk_gen.v | 13 +++++++++ fsm/rtl/top.v | 42 ++++++++++++++++++++++++++++ fsm/sim/top.cc | 47 ++++++++++++++++++++++++++++++++ 7 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 fsm/Makefile create mode 100644 fsm/constraints/iceFUN.pcf create mode 100644 fsm/constraints/timing.py create mode 100644 fsm/rtl/clk_gen.v create mode 100644 fsm/rtl/top.v create mode 100644 fsm/sim/top.cc diff --git a/.gitignore b/.gitignore index 25e0f01..a1220e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -*/obj_dir */build -*/*.bin -*/*.asc -*/*.json +*/obj_dir +*/diagram diff --git a/fsm/Makefile b/fsm/Makefile new file mode 100644 index 0000000..d9d3aac --- /dev/null +++ b/fsm/Makefile @@ -0,0 +1,56 @@ +SIM_TARGET = build/top +BIN_TARGET = build/top.bin +PCF = constraints/iceFUN.pcf +TIMING = constraints/timing.py +YOSYS = yosys +PNR = nextpnr-ice40 +IPACK = icepack +BURN = iceFUNprog + +VERILATOR=verilator +VERILATOR_ROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e "s/^.*=\s*//"') +VINC := $(VERILATOR_ROOT)/include + +RTL_SRC := $(wildcard rtl/*.v) +SIM_SRC := $(wildcard sim/*.cc) +BUILD_DIR := ./build + +.PHONY: all burn +all: $(SIM_TARGET) $(BIN_TARGET) + +# -GWIDTH=5 allows passing parameter to verilog module +$(BUILD_DIR)/Vtop.cc: $(RTL_SRC) + @echo "Running verilator" + @mkdir -p $(BUILD_DIR) + @$(VERILATOR) --trace -Wall -GWIDTH=10 -cc $^ --top-module top\ + --Mdir $(BUILD_DIR) --timescale-override 10ns/1ns + +$(BUILD_DIR)/Vtop__ALL.a: $(BUILD_DIR)/Vtop.cc + @make --no-print-directory -C $(BUILD_DIR) -f Vtop.mk + +# std=c++11 flag is needed as of verilator v4.100 +$(SIM_TARGET): $(SIM_SRC) $(BUILD_DIR)/Vtop__ALL.a + @echo "Compiling simulation executable" + @g++ -I$(VINC) -I$(BUILD_DIR) -std=c++14 $(VINC)/verilated.cpp\ + $(VINC)/verilated_vcd_c.cpp $^ -o $@ + @echo "Run simulation with ./$(SIM_TARGET)" + +$(BUILD_DIR)/top.json: $(RTL_SRC) + @echo "Synthesizing ..." + @mkdir -p $(BUILD_DIR) + @$(YOSYS) -p "synth_ice40 -top top -json build/top.json" -q $^ + +$(BIN_TARGET): $(BUILD_DIR)/top.json $(PCF) $(TIMING) + @echo "Routing and building binary stream ..." + @$(PNR) -r --hx8k --json $< --package cb132 \ + --asc $(BUILD_DIR)/top.asc --opt-timing --pcf $(PCF) \ + --pre-pack $(TIMING) -l $(BUILD_DIR)/pnr_report.txt -q + @$(IPACK) $(BUILD_DIR)/top.asc $@ + @echo "Done!" + +burn: $(BIN_TARGET) + @$(BURN) $< + +.PHONY: clean +clean: + rm -rf $(BUILD_DIR) diff --git a/fsm/constraints/iceFUN.pcf b/fsm/constraints/iceFUN.pcf new file mode 100644 index 0000000..2e2c606 --- /dev/null +++ b/fsm/constraints/iceFUN.pcf @@ -0,0 +1,12 @@ +# For iceFUN board + +set_io --warn-no-port i_clk P7 +set_io --warn-no-port lcol1 A12 +set_io --warn-no-port o_led[0] C10 +set_io --warn-no-port o_led[1] A10 +set_io --warn-no-port o_led[2] D7 +set_io --warn-no-port o_led[3] D6 +set_io --warn-no-port o_led[4] A7 +set_io --warn-no-port o_led[5] C7 +set_io --warn-no-port o_led[6] A4 +set_io --warn-no-port o_led[7] C4 diff --git a/fsm/constraints/timing.py b/fsm/constraints/timing.py new file mode 100644 index 0000000..f949a2c --- /dev/null +++ b/fsm/constraints/timing.py @@ -0,0 +1 @@ +ctx.addClock("i_clk", 100) diff --git a/fsm/rtl/clk_gen.v b/fsm/rtl/clk_gen.v new file mode 100644 index 0000000..491320f --- /dev/null +++ b/fsm/rtl/clk_gen.v @@ -0,0 +1,13 @@ +`default_nettype none +// dummy clock generator, should be replaced by a PLL clock gen eventually +module clk_gen( + input wire i_clk, + output wire o_clk +); + +assign o_clk = i_clk; + +endmodule +// Local Variables: +// verilog-library-directories:(".." "./rtl" ".") +// End: diff --git a/fsm/rtl/top.v b/fsm/rtl/top.v new file mode 100644 index 0000000..3366aa1 --- /dev/null +++ b/fsm/rtl/top.v @@ -0,0 +1,42 @@ +`default_nettype none + +module top(i_clk, o_led, lcol1); + parameter WIDTH = 22; + input wire i_clk; + output reg [7:0] o_led; + output wire lcol1; + + wire clk_12MHz; + + clk_gen clk_gen_0 (/*autoinst*/ + // Outputs + .o_clk (clk_12MHz), + // Inputs + .i_clk (i_clk)); + + reg [WIDTH-1:0] counter; + reg [7:0] obuf; // output buffer, take into account the icefun use active low LED + reg strobe; + + initial begin + obuf = 8'h1; + {strobe, counter} = 0; + end + + always @(posedge clk_12MHz) + {strobe, counter} <= counter + 1'b1; + + // shifting bit, to the left + always @(posedge clk_12MHz) + if (strobe) + obuf <= {obuf[6:0], obuf[7]}; + + always @(*) + o_led = ~obuf; + + assign lcol1 = 1'b0; +endmodule + +// Local Variables: +// verilog-library-directories:(".." "./rtl" ".") +// End: diff --git a/fsm/sim/top.cc b/fsm/sim/top.cc new file mode 100644 index 0000000..449c98c --- /dev/null +++ b/fsm/sim/top.cc @@ -0,0 +1,47 @@ +#include +#include +#include "verilated.h" +#include "verilated_vcd_c.h" +#include "Vtop.h" + +void tick(int tickcount, Vtop *tb, VerilatedVcdC* tfp) { + tb->eval(); + if (tfp) + tfp->dump(tickcount * 10 - 2); + tb->i_clk = 1; + tb->eval(); + if (tfp) + tfp->dump(tickcount * 10); + tb->i_clk = 0; + tb->eval(); + if (tfp) { + tfp->dump(tickcount * 10 + 5); + tfp->flush(); + } +} + +int main(int argc, char **argv) { + // Call commandArgs first! + Verilated::commandArgs(argc, argv); + + // Instantiate our design + Vtop *tb = new Vtop; + Verilated::traceEverOn(true); + VerilatedVcdC* tfp = new VerilatedVcdC; + + tb->trace(tfp, 00); + tfp->open("build/waveform.vcd"); + + unsigned tickcount = 0; + int last_led = tb->o_led; + + for(int k=0; k<(1 << 12); k++) { + tick(++tickcount, tb, tfp); + + if (last_led != tb->o_led) { + printf("k = %7d, led = %d\n", k, tb->o_led); + } + + last_led = tb->o_led; + } +}