Initial commit
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user