test and simulate spi_switch
This commit is contained in:
parent
36e5b964d5
commit
90a49b6091
|
@ -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/
|
|
@ -6,7 +6,9 @@
|
||||||
module spi_switch #(
|
module spi_switch #(
|
||||||
parameter PORTS = 3
|
parameter PORTS = 3
|
||||||
) (
|
) (
|
||||||
|
/* verilator lint_off UNUSEDSIGNAL */
|
||||||
input [PORTS-1:0] select,
|
input [PORTS-1:0] select,
|
||||||
|
/* verilator lint_on UNUSEDSIGNAL */
|
||||||
|
|
||||||
output reg mosi,
|
output reg mosi,
|
||||||
input miso,
|
input miso,
|
||||||
|
@ -23,10 +25,10 @@ module spi_switch #(
|
||||||
Do things the old, dumb way instead.
|
Do things the old, dumb way instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`define do_select(n) \
|
`define do_select(n) \
|
||||||
mosi = mosi_ports[n]; \
|
mosi = mosi_ports[n]; \
|
||||||
miso_ports[n] = miso; \
|
miso_ports = {{(PORTS-1){1'b0}},miso} << n; \
|
||||||
sck = sck_ports[n]; \
|
sck = sck_ports[n]; \
|
||||||
ss_L = ss_L_ports[n]
|
ss_L = ss_L_ports[n]
|
||||||
|
|
||||||
`define check_select(n) \
|
`define check_select(n) \
|
||||||
|
@ -37,7 +39,9 @@ module spi_switch #(
|
||||||
generate if (PORTS == 3) always @(*) begin
|
generate if (PORTS == 3) always @(*) begin
|
||||||
`check_select(2)
|
`check_select(2)
|
||||||
else `check_select(1)
|
else `check_select(1)
|
||||||
else `do_select(0);
|
else begin
|
||||||
|
`do_select(0);
|
||||||
|
end
|
||||||
end else always @(*) begin
|
end else always @(*) begin
|
||||||
`check_select(1)
|
`check_select(1)
|
||||||
else `do_select(0);
|
else `do_select(0);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ template <class TOP> class TB {
|
||||||
public:
|
public:
|
||||||
TOP mod;
|
TOP mod;
|
||||||
|
|
||||||
TB(int argc, char *argv[], int _bailout = 0) : mod(), bailout(_bailout) {
|
TB(int _bailout = 0) : mod(), bailout(_bailout) {
|
||||||
mod.clk = 0;
|
mod.clk = 0;
|
||||||
tick_count = 0;
|
tick_count = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
static inline void _assert(const char *file, int line, const char *exp, bool ev, const char *fmt, ...) {
|
static inline void _assert(const char *file, int line, const char *exp, bool ev, const char *fmt, ...) {
|
||||||
|
|
|
@ -87,7 +87,7 @@ int main(int argc, char *argv[]) {
|
||||||
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
||||||
Verilated::fatalOnError(false);
|
Verilated::fatalOnError(false);
|
||||||
|
|
||||||
tb = new TB<Vbram_interface_sim>(argc, argv);
|
tb = new TB<Vbram_interface_sim>();
|
||||||
|
|
||||||
printf("test basic read/write\n");
|
printf("test basic read/write\n");
|
||||||
refresh_data();
|
refresh_data();
|
||||||
|
|
|
@ -298,6 +298,8 @@ class CryoSNOM1SoC(SoCCore):
|
||||||
sys_clk_freq = int(100e6)
|
sys_clk_freq = int(100e6)
|
||||||
platform = board_spec.Platform(variant=variant, toolchain="symbiflow")
|
platform = board_spec.Platform(variant=variant, toolchain="symbiflow")
|
||||||
self.submodules.crg = _CRG(platform, sys_clk_freq, True)
|
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.v")
|
||||||
platform.add_source("rtl/spi/spi_master_ss_no_write.v")
|
platform.add_source("rtl/spi/spi_master_ss_no_write.v")
|
||||||
platform.add_source("rtl/control_loop/sign_extend.v")
|
platform.add_source("rtl/control_loop/sign_extend.v")
|
||||||
|
|
Loading…
Reference in New Issue