Commit d93f29f4 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[hdl] WIP to introduce a testbench for the WB SPI master.

This is not working yet, to be continued.
Signed-off-by: Dimitris Lampridis's avatarDimitris Lampridis <dimitris.lampridis@cern.ch>
parent 85964c94
sim_tool = "modelsim"
sim_top = "main"
action = "simulation"
vcom_opt = "-93 -mixedsvvh"
include_dirs = [
"../../../../sim",
]
files = [
"main.sv",
]
modules = {
"local" : [
"../../../../",
],
}
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// General Cores Library
// https://www.ohwr.org/project/general-cores
//------------------------------------------------------------------------------
//
// unit name: main
//
// description: Testbench for the WB SPI master module
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`timescale 1ns/1ns
`include "spi_sim.svh"
`include "vhd_wishbone_master.svh"
import wishbone_pkg::*;
module main;
wire spi_irq;
reg clk_sys = 0;
reg rst_n;
always #5ns clk_sys <= ~clk_sys;
initial begin
rst_n <= 0;
repeat(10) @(posedge clk_sys);
rst_n <= 1;
end
IVHDWishboneMaster host(clk_sys, rst_n);
IFACE_SPI ispi();
xwb_spi #
(
.g_interface_mode (0), // Classic
.g_address_granularity (0), // Byte
.g_divider_len (16),
.g_max_char_len (8),
.g_num_slaves (1)
)
DUT
(
.clk_sys_i (clk_sys),
.rst_n_i (rst_n),
.slave_i (host.out),
.slave_o (host.in),
.desc_o (),
.int_o (spi_irq),
.pad_cs_o (ispi.cs_n),
.pad_sclk_o (ispi.sclk),
.pad_mosi_o (ispi.mosi),
.pad_miso_i (ispi.miso_out)
);
CSPI_Slave spi;
CBusAccessor wb;
viSpiSlave spi_iface = ispi.slave;
initial begin
uint64_t val;
$timeformat (-6, 3, "us", 10);
wb = host.get_accessor();
wb.set_default_xfer_size(4);
spi = new(spi_iface, 8);
spi.run();
fork
begin
#10us;
for (int i = 0; i < 4; i++) begin
automatic bit cpol = i / 2;
automatic bit cpha = i % 2;
spi.set_mode(~cpol, cpha);
val = 'h1008;
val |= cpol << 10;
val |= cpha << 9;
$display("%.4x, %0d, %0d",val, ~cpol, cpha);
wb.write('h10, val);
wb.write('h14, 'h4);
wb.write('h00, 'h85);
wb.write('h18, 'h1);
wb.write('h10, val | 'h100);
#1us;
wb.read('h10, val);
#10us;
wb.write('h00, 'h85);
wb.write('h10, val | 'h100);
#1us;
wb.read('h10, val);
#10us;
end
$finish;
end
begin
automatic bit data[] = new[8];
automatic bit [7:0] data_packed;
forever @(posedge spi_irq) begin
spi.get_data(data);
data_packed = { << {data} };
$display("0b%b (0x%h)", data_packed, data_packed);
end
end
join
end
endmodule // main
# Modelsim run script with full logging for debugging
# execute: vsim -do "run.do"
vsim -quiet -t 1ns -L unisim -classdebug -voptargs=+acc work.main
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
log -r /*
run -all
# Modelsim run script for continuous integration
# execute: vsim -c -do "run_ci.do"
vsim -quiet -t 1ns -L unisim work.main
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
run -all
exit
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// General Cores Library
// https://www.ohwr.org/project/general-cores
//------------------------------------------------------------------------------
//
// unit name: IFACE_SPI, CSPI_Slave
//
// description: Collection of interfaces and classes for
// implementing SPI testbenches.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef _SPI_SIM
`define _SPI_SIM
interface IFACE_SPI ();
logic sclk;
logic mosi;
logic miso_in;
logic miso_out;
logic cs_n;
modport master
(
output sclk,
output mosi,
input miso_in,
output cs_n);
modport slave
(
input sclk,
input mosi,
output miso_out,
input cs_n);
assign miso_in = cs_n? 'bz : miso_out;
endinterface // IFACE_SPI
typedef virtual IFACE_SPI.master viSpiMaster;
typedef virtual IFACE_SPI.slave viSpiSlave;
class CSPI_Slave;
protected viSpiSlave spi;
protected bit shift_reg[];
protected int size;
protected int cpol;
protected int cpha;
// size defines the size of the slave SPI register
function new(viSpiSlave spi,
int size = 8,
int cpol = 0,
int cpha = 0);
int i;
this.spi = spi;
this.size = size;
this.shift_reg = new[size];
set_mode(cpol, cpha);
fork
spi.miso_out = 0;
forever @(posedge spi.sclk) begin
if (spi.cs_n == 1'b0)
begin
spi.miso_out = shift_reg[size-1];
for (i = size - 1; i > 0; i--)
shift_reg[i] = shift_reg[i-1];
shift_reg[0] = spi.mosi;
end
end
join_none
endfunction // new
function void set_mode(int cpol, int cpha);
this.cpol = cpol;
this.cpha = cpha;
endfunction // set_mode
task run();
endtask // run
task set_data(input bit data[]);
shift_reg = data;
endtask // set_data
task get_data(ref bit data[]);
data = shift_reg;
endtask // set_data
endclass // CSPI_Slave
`endif // _SPI_SIM
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment