Initial commit

This commit is contained in:
Nikolay Puzanov
2021-02-28 18:59:56 +03:00
parent ff795d2b6e
commit 2fbacc0544
61 changed files with 6063 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
-I./obj_dir
-I/usr/share/verilator/include

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

@@ -0,0 +1,2 @@
obj_dir
*.vcd

View 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

View File

@@ -0,0 +1 @@
../../source/fig_circle_8x8.rom

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

View 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

View 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

View File

@@ -0,0 +1 @@
../../source/quadrant_256.rom

View 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;
}

View 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