Initial commit
This commit is contained in:
5
testbench/.dir-locals.el
Normal file
5
testbench/.dir-locals.el
Normal file
@@ -0,0 +1,5 @@
|
||||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((verilog-mode . ((flycheck-verilator-include-path . ("." "../source"))
|
||||
(verilog-library-directories . ("." "../source")))))
|
||||
5
testbench/.gitignore
vendored
Normal file
5
testbench/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
*.out
|
||||
*.bin
|
||||
*.vcd
|
||||
*.gtkw
|
||||
filtered.txt
|
||||
31
testbench/Makefile
Normal file
31
testbench/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
VC = iverilog
|
||||
VI = vvp
|
||||
|
||||
#SOURCES = ../source/lcd_320x240_spi.sv
|
||||
SOURCES = $(wildcard ../source/*.sv)
|
||||
SOURCES += ../../local/share/yosys/ice40/cells_sim.v
|
||||
|
||||
VFLAGS = -g2012 -I../source
|
||||
TBS = $(wildcard tb_*.sv)
|
||||
DEFINES = -D TESTBENCH
|
||||
VCDDEPS = $(TBS:.sv=.vcd)
|
||||
BINDEPS = $(TBS:.sv=.bin)
|
||||
|
||||
all: $(VCDDEPS)
|
||||
|
||||
.SECONDARY:
|
||||
#.SILENT: $(VCDDEPS) $(BINDEPS) clean
|
||||
|
||||
%.vcd: %.bin
|
||||
@echo "Simulate :" $(<:.bin=.sv)
|
||||
$(VI) $< #> $(<:.bin=.out)
|
||||
|
||||
%.bin: %.sv $(SOURCES)
|
||||
@echo "Compile :" $(@:.bin=.sv)
|
||||
$(VC) $(VFLAGS) $(DEFINES) -D DUMPFILE=\"$(@:.bin=.vcd)\" -o $@ $< $(SOURCES)
|
||||
|
||||
clean:
|
||||
@echo "Remove *.bin, *.vcd, *.out"
|
||||
rm -rf *.bin
|
||||
rm -rf *.out
|
||||
rm -rf *.vcd
|
||||
1
testbench/fig_circle_8x8.rom
Symbolic link
1
testbench/fig_circle_8x8.rom
Symbolic link
@@ -0,0 +1 @@
|
||||
../source/fig_circle_8x8.rom
|
||||
9
testbench/fir-magn.m
Normal file
9
testbench/fir-magn.m
Normal file
@@ -0,0 +1,9 @@
|
||||
pkg load signal
|
||||
|
||||
data = csvread("filtered.txt");
|
||||
data = data(8:length(data));
|
||||
spec = abs(fft(data ./ 32768));
|
||||
len = length(data);
|
||||
x = 1:len/2;
|
||||
|
||||
plot(x ./ len, mag2db(spec(1:len/2)));
|
||||
1
testbench/fir_425_50hz_100hz_0db_40db.rom
Symbolic link
1
testbench/fir_425_50hz_100hz_0db_40db.rom
Symbolic link
@@ -0,0 +1 @@
|
||||
../source/fir_425_50hz_100hz_0db_40db.rom
|
||||
2
testbench/lcd-model/.clang_complete
Normal file
2
testbench/lcd-model/.clang_complete
Normal file
@@ -0,0 +1,2 @@
|
||||
-I./obj_dir
|
||||
-I/usr/share/verilator/include
|
||||
5
testbench/lcd-model/.dir-locals.el
Normal file
5
testbench/lcd-model/.dir-locals.el
Normal file
@@ -0,0 +1,5 @@
|
||||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((verilog-mode . ((flycheck-verilator-include-path . ("." "../../source"))
|
||||
(verilog-library-directories . ("." "../../source")))))
|
||||
2
testbench/lcd-model/.gitignore
vendored
Normal file
2
testbench/lcd-model/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
obj_dir
|
||||
*.vcd
|
||||
31
testbench/lcd-model/Makefile
Normal file
31
testbench/lcd-model/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
SOURCE_DIR = ../../source
|
||||
|
||||
SOURCES = testbench_top.cpp \
|
||||
testbench_top.sv \
|
||||
lcd_ili9341_4spi.sv \
|
||||
$(SOURCE_DIR)/sugar_lissajous.sv \
|
||||
$(SOURCE_DIR)/pll_lock_reset.sv \
|
||||
$(SOURCE_DIR)/pll.sv \
|
||||
$(SOURCE_DIR)/mcp3201_ma.sv \
|
||||
$(SOURCE_DIR)/lfsr.sv \
|
||||
$(SOURCE_DIR)/lcd_top.sv \
|
||||
$(SOURCE_DIR)/lcd_spi.sv \
|
||||
$(SOURCE_DIR)/ice40_spram.sv \
|
||||
$(SOURCE_DIR)/ice40_mac16x16.sv
|
||||
|
||||
SOURCES += ../../../local/share/yosys/ice40/cells_sim.v
|
||||
|
||||
TOP_MODULE = testbench_top
|
||||
|
||||
FLAGS = -DTESTBENCH -Wno-WIDTH -cc -I$(SOURCE_DIR) --top-module $(TOP_MODULE) +1800-2017ext+sv -I$(SOURCE_DIR)
|
||||
#FLAGS += --threads 8
|
||||
FLAGS += --trace
|
||||
|
||||
all: $(SOURCES)
|
||||
verilator $(FLAGS) --exe --build -o $(TOP_MODULE) $(SOURCES)
|
||||
|
||||
pre:
|
||||
verilator $(FLAGS) -o $(TOP_MODULE) $(SOURCES)
|
||||
|
||||
clean:
|
||||
rm -rf obj_dir
|
||||
1
testbench/lcd-model/fig_circle_8x8.rom
Symbolic link
1
testbench/lcd-model/fig_circle_8x8.rom
Symbolic link
@@ -0,0 +1 @@
|
||||
../../source/fig_circle_8x8.rom
|
||||
80
testbench/lcd-model/frontend.rkt
Executable file
80
testbench/lcd-model/frontend.rkt
Executable file
@@ -0,0 +1,80 @@
|
||||
#! /usr/bin/env racket
|
||||
#lang racket/gui
|
||||
|
||||
(require racket/gui/base)
|
||||
|
||||
(define display-width 240)
|
||||
(define display-height 320)
|
||||
(define fb-size (* display-width display-height))
|
||||
|
||||
(define (set-pixel! fb x y r g b)
|
||||
(let ((i (* 4 (+ x (* y display-width)))))
|
||||
(bytes-set! fb (+ i 0) 255)
|
||||
(bytes-set! fb (+ i 1) r)
|
||||
(bytes-set! fb (+ i 2) g)
|
||||
(bytes-set! fb (+ i 3) b)))
|
||||
|
||||
(define (clear-screen fb r g b)
|
||||
(for-each
|
||||
(lambda (n)
|
||||
(let ((n (* n 4)))
|
||||
(bytes-set! fb (+ n 0) 255)
|
||||
(bytes-set! fb (+ n 1) r)
|
||||
(bytes-set! fb (+ n 2) g)
|
||||
(bytes-set! fb (+ n 3) b)))
|
||||
(range fb-size)))
|
||||
|
||||
;;; MAIN
|
||||
(let* ((frame-buffer (make-bytes (* fb-size 4)))
|
||||
(frame-bitmap (make-bitmap display-width display-height))
|
||||
|
||||
(frame (new frame%
|
||||
(label "LCD")
|
||||
(min-width display-width)
|
||||
(min-height display-height)
|
||||
(stretchable-width #f)
|
||||
(stretchable-height #f)))
|
||||
|
||||
(canvas (new canvas% (parent frame)
|
||||
(paint-callback
|
||||
(lambda (canvas dc)
|
||||
(send frame-bitmap
|
||||
set-argb-pixels 0 0
|
||||
display-width display-height
|
||||
frame-buffer)
|
||||
(send dc draw-bitmap frame-bitmap 0 0)))))
|
||||
|
||||
(cmdl (current-command-line-arguments))
|
||||
(pipe (if (zero? (vector-length cmdl)) #f (vector-ref cmdl 0))))
|
||||
|
||||
|
||||
(clear-screen frame-buffer 50 100 150)
|
||||
(send frame show #t)
|
||||
|
||||
;; Read pixels data
|
||||
(thread (λ ()
|
||||
(let ((thunk
|
||||
(lambda ()
|
||||
(let loop ()
|
||||
(let ((s (read-line)))
|
||||
(if (eof-object? s)
|
||||
(loop) ;; (send frame show #f)
|
||||
(let ((l (string-split s)))
|
||||
(when (= 5 (length l))
|
||||
(let* ((x (string->number (list-ref l 0)))
|
||||
(y (string->number (list-ref l 1)))
|
||||
(r (string->number (list-ref l 2)))
|
||||
(g (string->number (list-ref l 3)))
|
||||
(b (string->number (list-ref l 4))))
|
||||
(set-pixel! frame-buffer x y r g b)))
|
||||
(loop))))))))
|
||||
(if pipe
|
||||
(with-input-from-file "lcd_pipe" thunk)
|
||||
(thunk)))))
|
||||
|
||||
;; Refresh screen
|
||||
(thread (lambda ()
|
||||
(let loop ()
|
||||
(send canvas refresh)
|
||||
(sleep 0.02)
|
||||
(loop)))))
|
||||
156
testbench/lcd-model/lcd_ili9341_4spi.sv
Normal file
156
testbench/lcd-model/lcd_ili9341_4spi.sv
Normal file
@@ -0,0 +1,156 @@
|
||||
`timescale 1ns/100ps
|
||||
`default_nettype none
|
||||
|
||||
module lcd_ili9341_4spi
|
||||
(input wire clock,
|
||||
input wire reset,
|
||||
|
||||
input wire csn_i,
|
||||
input wire clk_i,
|
||||
input wire sdi_i,
|
||||
input wire dcn_i,
|
||||
|
||||
output int x_o,
|
||||
output int y_o,
|
||||
output logic [7:0] r_o,
|
||||
output logic [7:0] g_o,
|
||||
output logic [7:0] b_o,
|
||||
output logic strobe_o);
|
||||
|
||||
logic [7:0] readed;
|
||||
logic [7:0] spi_sr;
|
||||
int bit_cntr;
|
||||
logic clk_prev;
|
||||
logic rstrobe;
|
||||
|
||||
always_ff @ (posedge clock) clk_prev <= clk_i;
|
||||
|
||||
always_ff @(posedge clock, posedge csn_i)
|
||||
if (csn_i || reset) begin
|
||||
bit_cntr <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_prev == 1'b0 &&
|
||||
clk_i == 1'b1)
|
||||
begin
|
||||
spi_sr <= { spi_sr[6:0], sdi_i };
|
||||
bit_cntr <= bit_cntr + 1;
|
||||
end
|
||||
|
||||
if (bit_cntr == 8) begin
|
||||
readed <= spi_sr;
|
||||
rstrobe <= 1'b1;
|
||||
bit_cntr <= 0;
|
||||
end
|
||||
else
|
||||
rstrobe <= 1'b0;
|
||||
end
|
||||
|
||||
enum int unsigned {
|
||||
ST_IDLE = 0,
|
||||
ST_CADDR,
|
||||
ST_PADDR,
|
||||
ST_MEM_WRITE
|
||||
} state;
|
||||
|
||||
logic [15:0] x_beg;
|
||||
logic [15:0] x_end;
|
||||
logic [15:0] y_beg;
|
||||
logic [15:0] y_end;
|
||||
|
||||
initial begin
|
||||
x_beg = 0;
|
||||
x_end = 239;
|
||||
y_beg = 0;
|
||||
y_end = 319;
|
||||
end
|
||||
|
||||
int n;
|
||||
int x, y;
|
||||
|
||||
logic [7:0] tmp;
|
||||
|
||||
always_ff @ (posedge clock, posedge csn_i)
|
||||
if (csn_i || reset) begin
|
||||
state <= ST_IDLE;
|
||||
n <= 0;
|
||||
strobe_o <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
strobe_o <= 1'b0;
|
||||
|
||||
if (rstrobe) begin
|
||||
if (~dcn_i) begin
|
||||
case (readed)
|
||||
8'h2a: state <= ST_CADDR;
|
||||
8'h2b: state <= ST_PADDR;
|
||||
8'h2c: begin
|
||||
x <= int'(x_beg);
|
||||
y <= int'(y_beg);
|
||||
state <= ST_MEM_WRITE;
|
||||
end
|
||||
default: begin end
|
||||
endcase
|
||||
|
||||
n <= 0;
|
||||
end
|
||||
else
|
||||
case (state)
|
||||
ST_CADDR: begin
|
||||
n <= n + 1;
|
||||
|
||||
case (n)
|
||||
0: x_beg[15:8] <= readed;
|
||||
1: x_beg[7:0] <= readed;
|
||||
2: x_end[15:8] <= readed;
|
||||
3: x_end[7:0] <= readed;
|
||||
endcase
|
||||
end
|
||||
|
||||
ST_PADDR: begin
|
||||
n <= n + 1;
|
||||
|
||||
case (n)
|
||||
0: y_beg[15:8] <= readed;
|
||||
1: y_beg[7:0] <= readed;
|
||||
2: y_end[15:8] <= readed;
|
||||
3: y_end[7:0] <= readed;
|
||||
endcase
|
||||
end
|
||||
|
||||
ST_MEM_WRITE: begin
|
||||
if (n == 0) begin
|
||||
n <= 1;
|
||||
tmp <= readed;
|
||||
end
|
||||
else begin
|
||||
n <= 0;
|
||||
|
||||
// $display("%d %d %d %d %d", x, y,
|
||||
// { tmp[7:3], 1'b0 },
|
||||
// { tmp[2:0], readed[7:5] },
|
||||
// { readed[4:0], 1'b0 });
|
||||
|
||||
x_o <= x;
|
||||
y_o <= y;
|
||||
r_o <= { 2'b00, tmp[7:3], 1'b0 };
|
||||
g_o <= { 2'b00, tmp[2:0], readed[7:5] };
|
||||
b_o <= { 2'b00, readed[4:0], 1'b0 };
|
||||
strobe_o <= 1'b1;
|
||||
|
||||
x <= x + 1;
|
||||
if (x == int'(x_end)) begin
|
||||
x <= int'(x_beg);
|
||||
|
||||
y <= y + 1;
|
||||
if (y == int'(y_end))
|
||||
y <= int'(y_beg);
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // lcd_ili9341_4spi
|
||||
61
testbench/lcd-model/lcd_init.rom
Normal file
61
testbench/lcd-model/lcd_init.rom
Normal file
@@ -0,0 +1,61 @@
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
000
|
||||
1
testbench/lcd-model/quadrant_256.rom
Symbolic link
1
testbench/lcd-model/quadrant_256.rom
Symbolic link
@@ -0,0 +1 @@
|
||||
../../source/quadrant_256.rom
|
||||
107
testbench/lcd-model/testbench_top.cpp
Normal file
107
testbench/lcd-model/testbench_top.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <verilated_vcd_c.h>
|
||||
#include "Vtestbench_top.h"
|
||||
|
||||
#define DUMPFILE "testbench_top.vcd"
|
||||
#define PIPE_FILE "lcd_pipe"
|
||||
|
||||
/* Clock period in timescale units
|
||||
* In datapath.sv uses 100ps time unit */
|
||||
#define CLOCK_PERIOD 2
|
||||
#define TIMESCALE 20000
|
||||
|
||||
/* Simulation time */
|
||||
uint64_t simtime = 0;
|
||||
|
||||
/* Clock cycle counter */
|
||||
uint64_t cycle = 0;
|
||||
|
||||
/* Called by $time in Verilog */
|
||||
double sc_time_stamp() {
|
||||
return simtime;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
/* Create model instance */
|
||||
Vtestbench_top *dp = new Vtestbench_top;
|
||||
|
||||
/* Enable trace if compiled with --trace flag */
|
||||
#if (VM_TRACE == 1)
|
||||
VerilatedVcdC *vcd = NULL;
|
||||
const char* trace_flag = Verilated::commandArgsPlusMatch("trace");
|
||||
|
||||
if (trace_flag && (strcmp(trace_flag, "+trace") == 0))
|
||||
{
|
||||
Verilated::traceEverOn(true);
|
||||
vcd = new VerilatedVcdC;
|
||||
dp->trace(vcd, 99);
|
||||
vcd->open(DUMPFILE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Open pipe */
|
||||
FILE *o_file = fopen(PIPE_FILE, "w");
|
||||
if (!o_file) {
|
||||
printf("ERROR: Can't open file/pipe '%s'\n", PIPE_FILE);
|
||||
delete dp;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int posedge_clock = 0;
|
||||
|
||||
int data_loops = 6;
|
||||
uint64_t check_cycle;
|
||||
|
||||
/* Initial */
|
||||
dp->reset = 1;
|
||||
dp->clock = 0;
|
||||
|
||||
while (!Verilated::gotFinish())
|
||||
{
|
||||
posedge_clock = 0;
|
||||
if ((simtime % (CLOCK_PERIOD/2)) == 0) {
|
||||
dp->clock = !dp->clock;
|
||||
if (dp->clock) {
|
||||
posedge_clock = 1;
|
||||
cycle ++;
|
||||
}
|
||||
}
|
||||
|
||||
/* release reset at 200 simulation cycle */
|
||||
if (simtime == 200) dp->reset = 0;
|
||||
|
||||
dp->eval();
|
||||
|
||||
/* ouput data */
|
||||
if (posedge_clock && !dp->reset && dp->strobe)
|
||||
fprintf(o_file, "%i %i %i %i %i\n",
|
||||
dp->x, dp->y, dp->r << 2, dp->g << 2, dp->b << 2);
|
||||
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd)
|
||||
vcd->dump(simtime * TIMESCALE);
|
||||
#endif
|
||||
|
||||
simtime ++;
|
||||
}
|
||||
|
||||
dp->final();
|
||||
printf("[%lu] Stop simulation\n", simtime);
|
||||
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd) vcd->close();
|
||||
#endif
|
||||
|
||||
fclose(o_file);
|
||||
delete dp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
testbench/lcd-model/testbench_top.sv
Normal file
41
testbench/lcd-model/testbench_top.sv
Normal file
@@ -0,0 +1,41 @@
|
||||
`timescale 1ns/100ps
|
||||
`default_nettype none
|
||||
|
||||
/* verilator lint_off PINMISSING */
|
||||
|
||||
module testbench_top
|
||||
(input wire clock,
|
||||
input wire reset,
|
||||
|
||||
output int x,
|
||||
output int y,
|
||||
output [7:0] r,
|
||||
output [7:0] g,
|
||||
output [7:0] b,
|
||||
output strobe);
|
||||
|
||||
logic csn, mosi, clk, dcn;
|
||||
|
||||
sugar_lissajous DUT
|
||||
(.CLK12(clock),
|
||||
.P1_3(1'b0),
|
||||
.P1_10(1'b1),
|
||||
.P2_3(dcn),
|
||||
.P2_9(clk),
|
||||
.P2_11(mosi),
|
||||
.P2_12(csn));
|
||||
|
||||
lcd_ili9341_4spi LCD
|
||||
(.clock, .reset,
|
||||
.csn_i(csn),
|
||||
.clk_i(clk),
|
||||
.sdi_i(mosi),
|
||||
.dcn_i(dcn),
|
||||
.x_o(x),
|
||||
.y_o(y),
|
||||
.r_o(r),
|
||||
.g_o(g),
|
||||
.b_o(b),
|
||||
.strobe_o(strobe));
|
||||
|
||||
endmodule // testbench_top
|
||||
1
testbench/lcd_init.rom
Symbolic link
1
testbench/lcd_init.rom
Symbolic link
@@ -0,0 +1 @@
|
||||
../source/lcd_init.rom
|
||||
1
testbench/quadrant_256.rom
Symbolic link
1
testbench/quadrant_256.rom
Symbolic link
@@ -0,0 +1 @@
|
||||
../source/quadrant_256.rom
|
||||
60
testbench/tb_circle.sv
Normal file
60
testbench/tb_circle.sv
Normal file
@@ -0,0 +1,60 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_circle;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock <= ~clock;
|
||||
|
||||
logic [9:0] angle;
|
||||
logic [7:0] r;
|
||||
logic [7:0] x0;
|
||||
logic [7:0] y0;
|
||||
logic [7:0] x;
|
||||
logic [7:0] y;
|
||||
logic req, ack;
|
||||
|
||||
circle_1024 DUT
|
||||
(.clock, .reset,
|
||||
.angle,
|
||||
.r,
|
||||
.x0,
|
||||
.y0,
|
||||
.x,
|
||||
.y,
|
||||
.req_i(req),
|
||||
.ack_o(ack));
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
req = 1'b0;
|
||||
repeat(10) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
|
||||
@(posedge clock) #1;
|
||||
|
||||
angle = '0;
|
||||
r = 120;
|
||||
x0 = 120;
|
||||
y0 = 128;
|
||||
|
||||
for (int i = 0; i < 1024; i ++) begin
|
||||
@(posedge clock) #1;
|
||||
req = 1'b1;
|
||||
|
||||
wait (ack);
|
||||
angle = angle + 1'b1;
|
||||
end
|
||||
req = 1'b0;
|
||||
|
||||
repeat(10) @(posedge clock) #1;
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_circle.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_circle
|
||||
70
testbench/tb_fig_drawer.sv
Normal file
70
testbench/tb_fig_drawer.sv
Normal file
@@ -0,0 +1,70 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_fig_drawer;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock <= ~clock;
|
||||
|
||||
logic [7:0] x;
|
||||
logic [8:0] y;
|
||||
logic [7:0] h, s, v;
|
||||
logic req, ack;
|
||||
|
||||
logic [7:0] fb_x;
|
||||
logic [8:0] fb_y;
|
||||
logic [15:0] fb_color;
|
||||
logic fb_req, fb_ack;
|
||||
|
||||
fig_drawer DUT
|
||||
(.clock, .reset,
|
||||
.x_i(x), .y_i(y),
|
||||
.h_i(h), .s_i(s), .v_i(v),
|
||||
.req_i(req), .ack_o(ack),
|
||||
|
||||
.fb_x_o(fb_x),
|
||||
.fb_y_o(fb_y),
|
||||
.fb_color_o(fb_color),
|
||||
.fb_req_o(fb_req),
|
||||
.fb_ack_i(fb_ack));
|
||||
|
||||
int fb_lat_n;
|
||||
always_ff @ (posedge clock) begin
|
||||
fb_ack <= 1'b0;
|
||||
|
||||
if (fb_req)
|
||||
if (fb_lat_n == 2) begin
|
||||
fb_ack <= 1'b1;
|
||||
fb_lat_n <= 0;
|
||||
end
|
||||
else fb_lat_n <= fb_lat_n + 1;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clock)
|
||||
if (ack)
|
||||
req <= 1'b0;
|
||||
|
||||
initial begin
|
||||
reset <= 1'b1;
|
||||
repeat(10) @(posedge clock);
|
||||
reset <= 1'b0;
|
||||
|
||||
@(posedge clock);
|
||||
x <= 'd20;
|
||||
y <= 'd50;
|
||||
h <= 50;
|
||||
s <= 100;
|
||||
v <= 150;
|
||||
req <= 1'b1;
|
||||
|
||||
repeat(1000) @(posedge clock);
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_fig_drawer.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_fig_drawer
|
||||
69
testbench/tb_fig_ring.sv
Normal file
69
testbench/tb_fig_ring.sv
Normal file
@@ -0,0 +1,69 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_fig_ring;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock <= ~clock;
|
||||
|
||||
logic pt_ack_o;
|
||||
logic [7:0] fig_x_o;
|
||||
logic [8:0] fig_y_o;
|
||||
logic [7:0] fig_h_o;
|
||||
logic [7:0] fig_s_o;
|
||||
logic [7:0] fig_v_o;
|
||||
logic fig_req_o;
|
||||
logic [7:0] pt_x;
|
||||
logic [7:0] pt_y;
|
||||
logic [7:0] pt_h;
|
||||
logic pt_req_i;
|
||||
logic fig_ack_i;
|
||||
|
||||
fig_ring DUT (/*AUTOINST*/
|
||||
// Outputs
|
||||
.pt_ack_o (pt_ack_o),
|
||||
.fig_x_o (fig_x_o[7:0]),
|
||||
.fig_y_o (fig_y_o[8:0]),
|
||||
.fig_h_o (fig_h_o[7:0]),
|
||||
.fig_s_o (fig_s_o[7:0]),
|
||||
.fig_v_o (fig_v_o[7:0]),
|
||||
.fig_req_o (fig_req_o),
|
||||
// Inputs
|
||||
.clock (clock),
|
||||
.reset (reset),
|
||||
.pt_x (pt_x[7:0]),
|
||||
.pt_y (pt_y[7:0]),
|
||||
.pt_h (pt_h[7:0]),
|
||||
.pt_req_i (pt_req_i),
|
||||
.fig_ack_i (fig_ack_i));
|
||||
|
||||
assign fig_ack_i = 1'b1;
|
||||
|
||||
always_ff @ (posedge clock)
|
||||
if (pt_ack_o)
|
||||
pt_req_i <= 1'b0;
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
pt_req_i = 1'b0;
|
||||
|
||||
repeat(10) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
|
||||
@(posedge clock) #1;
|
||||
pt_x = 0;
|
||||
pt_y = 0;
|
||||
pt_h = 100;
|
||||
pt_req_i = 1'b1;
|
||||
|
||||
repeat(1000) @(posedge clock) #1;
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_fig_ring.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_fig_ring
|
||||
66
testbench/tb_fir_filter.sv
Normal file
66
testbench/tb_fir_filter.sv
Normal file
@@ -0,0 +1,66 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_fir_filter;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock <= ~clock;
|
||||
|
||||
logic signed [15:0] data_i;
|
||||
logic signed [15:0] data_o;
|
||||
logic input_ready, output_valid;
|
||||
|
||||
localparam FILTER_LEN = 425;
|
||||
|
||||
fir_filter #(.LEN(FILTER_LEN),
|
||||
.COEFFS_ROM_FILE("fir_425_50hz_100hz_0db_40db.rom")) DUT
|
||||
(.clock, .reset,
|
||||
.data_i, .data_o,
|
||||
.ready_i(input_ready),
|
||||
.valid_o(output_valid));
|
||||
|
||||
event done;
|
||||
integer file_o;
|
||||
|
||||
initial begin
|
||||
file_o = $fopen("filtered.txt", "w");
|
||||
@(done);
|
||||
$fclose(file_o);
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
input_ready = 1'b0;
|
||||
|
||||
repeat(10) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
|
||||
@(posedge clock) #1;
|
||||
data_i = 16'd32767;
|
||||
input_ready = 1'b1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
wait (output_valid)
|
||||
$fdisplay(file_o, "%d", data_o);
|
||||
data_i = '0;
|
||||
|
||||
for (int i = 1; i < FILTER_LEN; i ++) begin
|
||||
@(posedge clock) #1;
|
||||
wait (output_valid)
|
||||
$fdisplay(file_o, "%d", data_o);
|
||||
end
|
||||
|
||||
->done;
|
||||
|
||||
repeat(10) @(posedge clock) #1;
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_fir_filter.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_fir_filter
|
||||
49
testbench/tb_hsl2rgb.sv
Normal file
49
testbench/tb_hsl2rgb.sv
Normal file
@@ -0,0 +1,49 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_hsl2rgb;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock <= ~clock;
|
||||
|
||||
logic [7:0] h, s, l;
|
||||
logic [7:0] r, g, b;
|
||||
logic valid, ready;
|
||||
|
||||
hsl2rgb DUT
|
||||
(.clock, .reset,
|
||||
.h, .s, .l,
|
||||
.ready_i(ready),
|
||||
.r, .g, .b,
|
||||
.valid_o(valid));
|
||||
|
||||
always_ff @ (posedge clock)
|
||||
if (valid)
|
||||
$display("%d %d %d", r, g, b);
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
ready = 1'b0;
|
||||
repeat(10) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
|
||||
@(posedge clock) #1;
|
||||
h = 8'd128;
|
||||
s = 8'd255;
|
||||
l = 8'd130;
|
||||
ready = 1'b1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
ready = 1'b0;
|
||||
|
||||
repeat(20) @(posedge clock);
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_hsl2rgb.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_hsl2rgb
|
||||
78
testbench/tb_hsv2rgb.sv
Normal file
78
testbench/tb_hsv2rgb.sv
Normal file
@@ -0,0 +1,78 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_hsv2rgb;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 100MHz (10ns period) */
|
||||
always #(10ns/2) clock <= ~clock;
|
||||
|
||||
logic [7:0] h, s, v;
|
||||
logic [7:0] r, g, b;
|
||||
logic valid, ready;
|
||||
|
||||
hsv2rgb DUT
|
||||
(.clock, .reset,
|
||||
.h, .s, .v,
|
||||
.ready_i(ready),
|
||||
.r, .g, .b,
|
||||
.valid_o(valid));
|
||||
|
||||
always_ff @ (posedge clock)
|
||||
if (valid)
|
||||
$display("%d %d %d", r, g, b);
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
ready = 1'b0;
|
||||
repeat(10) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
|
||||
@(posedge clock) #1;
|
||||
h = 8'd50;
|
||||
s = 8'd100;
|
||||
v = 8'd150;
|
||||
ready = 1'b1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
h = 8'dx;
|
||||
s = 8'dx;
|
||||
v = 8'dx;
|
||||
ready = 1'b0;
|
||||
|
||||
@(posedge clock) #1;
|
||||
@(posedge clock) #1;
|
||||
@(posedge clock) #1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
h = 8'd50;
|
||||
s = 8'd100;
|
||||
v = 8'd150;
|
||||
ready = 1'b1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
h = 8'd111;
|
||||
s = 8'd222;
|
||||
v = 8'd33;
|
||||
ready = 1'b1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
h = 8'd200;
|
||||
s = 8'd150;
|
||||
v = 8'd50;
|
||||
ready = 1'b1;
|
||||
|
||||
@(posedge clock) #1;
|
||||
ready = 1'b0;
|
||||
|
||||
|
||||
repeat(10) @(posedge clock);
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_hsv2rgb.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_hsv2rgb
|
||||
63
testbench/tb_lcd_spi.sv
Normal file
63
testbench/tb_lcd_spi.sv
Normal file
@@ -0,0 +1,63 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module tb_lcd_spi;
|
||||
logic clock = 1'b0;
|
||||
logic reset = 1'b1;
|
||||
|
||||
/* Master clock 50MHz (20ns period) */
|
||||
always #(20ns/2) clock <= ~clock;
|
||||
|
||||
logic [7:0] data;
|
||||
logic push, done;
|
||||
logic sclk, sdo;
|
||||
|
||||
lcd_spi #(.DATA_WIDTH(8),
|
||||
.SPI_CLK_PERIOD(16)) DUT
|
||||
(.clock, .reset,
|
||||
.data_i(data),
|
||||
.push_i(push),
|
||||
.done_o(done),
|
||||
.spi_clk_o(sclk),
|
||||
.spi_dat_o(sdo));
|
||||
|
||||
int state;
|
||||
|
||||
always_ff @(posedge clock)
|
||||
if (reset) begin
|
||||
push <= 1'b0;
|
||||
state <= 0;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
0: begin
|
||||
data <= $random;
|
||||
push <= 1'b1;
|
||||
state <= 1;
|
||||
end
|
||||
|
||||
1: begin
|
||||
if (done) begin
|
||||
//data <= $random;
|
||||
push <= 1'b0;
|
||||
state <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
initial begin
|
||||
reset = 1'b1;
|
||||
repeat(10) @(posedge clock) #1;
|
||||
reset = 1'b0;
|
||||
|
||||
repeat(1000) @(posedge clock);
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("tb_lcd_spi.vcd");
|
||||
$dumpvars;
|
||||
end
|
||||
|
||||
endmodule // tb_lcd_spi
|
||||
Reference in New Issue
Block a user