test and simulate spi_switch

This commit is contained in:
Peter McGoron 2023-03-14 15:42:41 +00:00
parent 36e5b964d5
commit 90a49b6091
7 changed files with 82 additions and 7 deletions

16
firmware/rtl/spi/Makefile Normal file
View File

@ -0,0 +1,16 @@
# Makefile for tests and hardware verification.
.PHONY: test clean
test: obj_dir/Vspi_switch
SRC= spi_switch.v spi_switch_sim.cpp
obj_dir/Vspi_switch.mk: $(SRC)
verilator --cc --exe -Wall \
$(SRC)
obj_dir/Vspi_switch: obj_dir/Vspi_switch.mk $(SRC)
cd obj_dir && make -f Vspi_switch.mk
./obj_dir/Vspi_switch
clean:
rm -rf obj_dir/

View File

@ -6,7 +6,9 @@
module spi_switch #(
parameter PORTS = 3
) (
/* verilator lint_off UNUSEDSIGNAL */
input [PORTS-1:0] select,
/* verilator lint_on UNUSEDSIGNAL */
output reg mosi,
input miso,
@ -23,10 +25,10 @@ module spi_switch #(
Do things the old, dumb way instead.
*/
`define do_select(n) \
mosi = mosi_ports[n]; \
miso_ports[n] = miso; \
sck = sck_ports[n]; \
`define do_select(n) \
mosi = mosi_ports[n]; \
miso_ports = {{(PORTS-1){1'b0}},miso} << n; \
sck = sck_ports[n]; \
ss_L = ss_L_ports[n]
`define check_select(n) \
@ -37,7 +39,9 @@ module spi_switch #(
generate if (PORTS == 3) always @(*) begin
`check_select(2)
else `check_select(1)
else `do_select(0);
else begin
`do_select(0);
end
end else always @(*) begin
`check_select(1)
else `do_select(0);

View File

@ -0,0 +1,51 @@
#include "../util.hpp"
#include "Vspi_switch.h"
Vspi_switch *tb;
static void set_and_check(unsigned int selected, unsigned int num, unsigned int expected) {
tb->miso = 1;
tb->mosi_ports = 1 << num;
tb->sck_ports = 1 << num;
tb->ss_L_ports = 1 << num;
tb->eval();
my_assert(tb->mosi == expected, "%u != %u", tb->mosi, expected);
my_assert(tb->sck == expected, "%u != %u", tb->sck, expected);
my_assert(tb->ss_L == expected, "%u != %u", tb->ss_L, expected);
my_assert(tb->miso_ports == 1 << selected, "%u != %u", tb->miso_ports, 1 << selected);
}
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
Verilated::traceEverOn(true);
tb = new Vspi_switch();
printf("Default behavior.\n");
tb->select = 0;
set_and_check(0, 0, 1);
set_and_check(0, 1, 0);
set_and_check(0, 2, 0);
printf("Selecting the first port.\n");
tb->select = 1;
set_and_check(0, 0, 1);
set_and_check(0, 1, 0);
set_and_check(0, 2, 0);
printf("Selecting the second port.\n");
tb->select = 1 << 1;
set_and_check(1, 0, 0);
set_and_check(1, 1, 1);
set_and_check(1, 2, 0);
printf("Selecting the third port.\n");
tb->select = 1 << 2;
set_and_check(2, 0, 0);
set_and_check(2, 1, 0);
set_and_check(2, 2, 1);
tb->final();
delete tb;
return 0;
}

View File

@ -10,7 +10,7 @@ template <class TOP> class TB {
public:
TOP mod;
TB(int argc, char *argv[], int _bailout = 0) : mod(), bailout(_bailout) {
TB(int _bailout = 0) : mod(), bailout(_bailout) {
mod.clk = 0;
tick_count = 0;
}

View File

@ -1,4 +1,6 @@
#pragma once
#include <cstdarg>
#include <cstdlib>
#include <cstdio>
static inline void _assert(const char *file, int line, const char *exp, bool ev, const char *fmt, ...) {

View File

@ -87,7 +87,7 @@ int main(int argc, char *argv[]) {
Verilated::traceEverOn(true);
Verilated::fatalOnError(false);
tb = new TB<Vbram_interface_sim>(argc, argv);
tb = new TB<Vbram_interface_sim>();
printf("test basic read/write\n");
refresh_data();

View File

@ -298,6 +298,8 @@ class CryoSNOM1SoC(SoCCore):
sys_clk_freq = int(100e6)
platform = board_spec.Platform(variant=variant, toolchain="symbiflow")
self.submodules.crg = _CRG(platform, sys_clk_freq, True)
platform.add_source("rtl/spi/spi_switch.v")
platform.add_source("rtl/spi/spi_master.v")
platform.add_source("rtl/spi/spi_master_ss.v")
platform.add_source("rtl/spi/spi_master_ss_no_write.v")
platform.add_source("rtl/control_loop/sign_extend.v")