Skip to content
Snippets Groups Projects
Commit 79e1ba3d authored by Tomasz Wlostowski's avatar Tomasz Wlostowski
Browse files

top level testbench

parent 0fbd4ec0
No related merge requests found
target = "xilinx"
action = "simulation"
syn_device = "XC6VLX130T"
fetchto = "../../ip_cores"
vlog_opt = "+incdir+../../sim +incdir+../../sim/wr-hdl"
files = [ "main.sv" ]
modules = { "local" : ["../../", "../../top/scb_test"] }
`timescale 1ns/1ps
`include "tbi_utils.sv"
`include "simdrv_wrsw_nic.svh"
`include "simdrv_rtu.sv"
`include "endpoint_regs.v"
`include "endpoint_mdio.v"
`include "if_wb_master.svh"
`include "if_wb_slave.svh"
`include "wb_packet_source.svh"
`include "wb_packet_sink.svh"
`include "scb_top_sim_svwrap.svh"
module main;
reg clk_ref=0;
reg clk_sys=0;
reg rst_n=0;
parameter g_num_ports = 6;
/* -----\/----- EXCLUDED -----\/-----
tbi_clock_rst_gen
#(
.g_rbclk_period(8002))
clkgen(
.clk_sys_o(clk_sys),
.clk_ref_o(clk_ref),
.rst_n_o(rst_n)
);
-----/\----- EXCLUDED -----/\----- */
always #8ns clk_sys <= ~clk_sys;
always #7.998ns clk_ref <= ~clk_ref;
// always #8ns clk_sys <= ~clk_sys;
// always #8ns clk_ref <= ~clk_ref;
initial begin
repeat(3) @(posedge clk_sys);
rst_n <= 1;
end
// assign clk_ref = clk_sys;
task automatic tx_test(ref int seed, input int n_tries, input int is_q,input int unvid, ref EthPacketSource src, ref EthPacketSink sink);
EthPacketGenerator gen = new;
EthPacket pkt, tmpl, pkt2;
EthPacket arr[];
int i,j;
arr = new[n_tries](arr);
gen.set_seed(seed);
tmpl = new;
tmpl.src = '{1,2,3,4,5,6};
tmpl.dst = '{'h00, 'h50, 'hca, 'hfe, 'hba, 'hbe};
tmpl.has_smac = 1;
tmpl.is_q = is_q;
tmpl.vid = 100;
tmpl.ethertype = 'h88f7;
//
gen.set_randomization(EthPacketGenerator::SEQ_PAYLOAD | EthPacketGenerator::SEQ_ID);
gen.set_template(tmpl);
gen.set_size(63, 257);
fork
for(i=0;i<n_tries;i++)
begin
pkt = gen.gen();
pkt.oob = TX_FID;
$display("Tx %d", i);
// pkt.dump();
src.send(pkt);
arr[i] = pkt;
// repeat(3000) @(posedge clk_sys);
// $display("Send: %d [dsize %d]", i+1,pkt.payload.size() + 14);
end
for(j=0;j<n_tries;j++)
begin
sink.recv(pkt2);
$display("rx %d", j);
if(unvid)
arr[j].is_q = 0;
if(!arr[j].equal(pkt2))
begin
$display("Fault at %d", j);
$display("Should be: ");
arr[j].dump();
$display("Is: ");
pkt2.dump();
//sfp $stop;
end
end // for (i=0;i<n_tries;i++)
join
seed = gen.get_seed();
endtask // tx_test
scb_top_sim_svwrap
#(
.g_num_ports(g_num_ports)
) DUT (
.clk_sys_i(clk_sys),
.clk_ref_i(clk_ref),
.rst_n_i(rst_n),
.cpu_irq(cpu_irq)
);
typedef struct {
CSimDrv_WR_Endpoint ep;
EthPacketSource send;
EthPacketSink recv;
} port_t;
port_t ports[$];
CSimDrv_NIC nic;
CRTUSimDriver rtu;
task automatic init_ports(ref port_t p[$], ref CWishboneAccessor wb);
int i;
for(i=0;i<g_num_ports;i++)
begin
port_t tmp;
CSimDrv_WR_Endpoint ep;
ep = new(wb, 'h30000 + i * 'h400);
ep.init();
tmp.ep = ep;
tmp.send = EthPacketSource'(DUT.to_port[i]);
tmp.recv = EthPacketSink'(DUT.from_port[i]);
p.push_back(tmp);
end
endtask // init_endpoints
task automatic init_nic(ref port_t p[$],ref CWishboneAccessor wb);
NICPacketSource nic_src;
NICPacketSink nic_snk;
port_t tmp;
nic = new(wb, 'h20000);
$display("NICInit");
nic.init();
$display("Done");
nic_src = new (nic);
nic_snk = new (nic);
$display("Src: %x\n",nic_src);
tmp.send = EthPacketSource'(nic_src);
tmp.recv = EthPacketSink'(nic_snk);
p.push_back(tmp);
endtask // init_nic
initial begin
uint64_t msr, i;
int seed;
rtu_vlan_entry_t def_vlan;
CWishboneAccessor cpu_acc = DUT.cpu.get_accessor();
repeat(200) @(posedge clk_sys);
$display("Startup!");
cpu_acc.set_mode(PIPELINED);
cpu_acc.write('h10304, (1<<3));
init_ports(ports, cpu_acc);
$display("InitNIC");
init_nic(ports, cpu_acc);
$display("Initialization done");
rtu = new;
rtu.set_bus(cpu_acc, 'h60000);
rtu.set_port_config(1, 1, 1, 1);
rtu.add_static_rule('{'h00, 'h50, 'hca, 'hfe, 'hba, 'hbe}, 1'h1);
// rtu.set_hash_poly();
def_vlan.port_mask = 32'hffffffff;
def_vlan.fid =0;
def_vlan.drop = 0;
def_vlan.has_prio =0;
def_vlan.prio_override = 0;
rtu.add_vlan_entry(0, def_vlan);
rtu.enable();
fork
begin
for(i=0;i<20;i++)
begin
$display("Try %d", i);
tx_test(seed, 20, 0, 0, ports[6].send, ports[0].recv);
end
end
forever begin
nic.update(DUT.U_Top.U_Wrapped_SCBCore.vic_irqs[0]);
@(posedge clk_sys);
end
join_none
end
/* -----\/----- EXCLUDED -----\/-----
#3us;
$display("Startup");
acc.write('h10304, (1<<3));
for (i=0;i<18;i++)
begin
acc.read('h30034 + i*'h400, msr);
$display("IDCODE [%d]: %x", i, msr);
end
ep = new (acc, 'h31000);
ep.init();
nic = new (acc, 'h20000);
nic.init();
$display("waiting for link");
fork
begin
tx_test(3, 0, 0, nic_src, nic_snk);
end
begin
forever begin
nic.update(!cpu_irq_n);
@(posedge clk_sys);
end
end
join
end // initial begin
-----/\----- EXCLUDED -----/\----- */
endmodule // main
make -f Makefile
vlog +incdir+../../sim +incdir+../../ip_cores/wr-cores/sim main.sv
vsim -L secureip -L unisim -t 10fs work.main -voptargs="+acc" +nowarn8684 +nowarn8683
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
do wave.do
radix -hexadecimal
run 100us
wave zoomfull
radix -hexadecimal
`timescale 1ns/1ps
`include "simdrv_defs.svh"
`include "simdrv_wr_endpoint.svh"
`include "if_wb_master.svh"
`include "if_wb_slave.svh"
function automatic bit f_next_8b10b_disparity8(bit cur_disp, bit k, bit [7:0] data);
const bit[0:31] c_disPar_6b = 32'b11101000100000011000000110010111;
const bit [0:7] c_disPar_4b = 8'b10001001;
bit dp4bit, dp6bit, new_disp;
dp4bit = c_disPar_4b[data[7:5]];
dp6bit = c_disPar_6b[data[4:0]];
new_disp = cur_disp;
case (cur_disp)
1'b0: if (k ^ dp6bit ^ dp4bit)
new_disp = 1;
1'b1: if (k ^ dp6bit ^ dp4bit)
new_disp = 0;
endcase // case (cur_disp)
if ( data[1:0] != 2'b0 && k)
new_disp = cur_disp;
return new_disp;
endfunction // f_next_8b10b_disparity8
function automatic bit f_next_8b10b_disparity16(bit cur_disp,bit[1:0] k, bit[15:0] data);
bit tmp;
bit [7:0] msb;
msb = data[15:0];
tmp = f_next_8b10b_disparity8(cur_disp, k[1], msb);
tmp = f_next_8b10b_disparity8(tmp, k[0], data[7:0]);
return tmp;
endfunction // f_next_8b10b_disparity16
module scb_top_sim_svwrap
(
clk_sys_i,
clk_ref_i,
rst_n_i,
cpu_irq
);
parameter g_num_ports = 6;
input clk_sys_i, clk_ref_i,rst_n_i;
output cpu_irq;
wire [g_num_ports-1:0] rbclk;
wire [18 * g_num_ports - 1:0] td, rd;
typedef struct {
logic rst;
logic loopen;
logic enable;
logic syncen;
logic [15:0] tx_data;
logic [1:0] tx_k;
} t_phyif_output;
typedef struct {
logic ref_clk;
logic tx_disparity;
logic tx_enc_err ;
logic [15:0] rx_data ;
logic rx_clk ;
logic [1:0] rx_k ;
logic rx_enc_err ;
logic rx_bitslide ;
} t_phyif_input;
t_phyif_output phys_out[g_num_ports];
t_phyif_input phys_in[g_num_ports];
WBPacketSource to_port[g_num_ports];
WBPacketSink from_port[g_num_ports];
int seed2;
IWishboneMaster #(32, 32) cpu(clk_sys_i, rst_n_i);
initial
begin
cpu.settings.cyc_on_stall = 1;
cpu.settings.addr_gran = BYTE;
end
reg [g_num_ports-1:0] clk_ref_phys = 0;
time periods[g_num_ports];
generate
genvar i;
for(i=0; i<g_num_ports; i++)
begin
initial forever #(periods[i]) clk_ref_phys[i] <= ~clk_ref_phys[i];
initial periods[i] = 8ns;
//$dist_uniform(seed2, 8ns, 8ns);
IWishboneMaster U_ep_wb (clk_sys_i, rst_n_i) ;
IWishboneMaster #(2,16) U_ep_src (clk_sys_i, rst_n_i) ;
IWishboneSlave #(2,16) U_ep_snk (clk_sys_i, rst_n_i) ;
wr_endpoint
#(
.g_simulation (1),
.g_pcs_16bit(1),
.g_rx_buffer_size (1024),
.g_with_rx_buffer (0),
.g_with_timestamper (1),
.g_with_dpi_classifier (1),
.g_with_vlans (0),
.g_with_rtu (0)
) DUT (
.clk_ref_i (clk_ref_phys[i]),
.clk_sys_i (clk_sys_i),
.clk_dmtd_i (clk_ref_i),
.rst_n_i (rst_n_i),
.pps_csync_p1_i (1'b0),
.phy_rst_o (phys_out[i].rst),
.phy_loopen_o (),
.phy_enable_o (),
.phy_syncen_o (),
.phy_ref_clk_i (phys_in[i].ref_clk),
.phy_tx_data_o (phys_out[i].tx_data),
.phy_tx_k_o (phys_out[i].tx_k),
.phy_tx_disparity_i (phys_in[i].tx_disparity),
.phy_tx_enc_err_i (phys_in[i].tx_enc_err),
.phy_rx_data_i (phys_in[i].rx_data),
.phy_rx_clk_i (phys_in[i].rx_clk),
.phy_rx_k_i (phys_in[i].rx_k),
.phy_rx_enc_err_i (phys_in[i].rx_enc_err),
.phy_rx_bitslide_i (5'b0),
.src_dat_o (U_ep_snk.slave.dat_i),
.src_adr_o (U_ep_snk.slave.adr),
.src_sel_o (U_ep_snk.slave.sel),
.src_cyc_o (U_ep_snk.slave.cyc),
.src_stb_o (U_ep_snk.slave.stb),
.src_we_o (U_ep_snk.slave.we),
.src_stall_i (U_ep_snk.slave.stall),
.src_ack_i (U_ep_snk.slave.ack),
.src_err_i(1'b0),
.snk_dat_i (U_ep_src.master.dat_o[15:0]),
.snk_adr_i (U_ep_src.master.adr[1:0]),
.snk_sel_i (U_ep_src.master.sel[1:0]),
.snk_cyc_i (U_ep_src.master.cyc),
.snk_stb_i (U_ep_src.master.stb),
.snk_we_i (U_ep_src.master.we),
.snk_stall_o (U_ep_src.master.stall),
.snk_ack_o (U_ep_src.master.ack),
.snk_err_o (U_ep_src.master.err),
.snk_rty_o (U_ep_src.master.rty),
.txtsu_ack_i (1'b1),
.rtu_full_i (1'b0),
.wb_cyc_i(U_ep_wb.master.cyc),
.wb_stb_i(U_ep_wb.master.stb),
.wb_we_i (U_ep_wb.master.we),
.wb_sel_i(U_ep_wb.master.sel),
.wb_adr_i(U_ep_wb.master.adr[7:0]),
.wb_dat_i(U_ep_wb.master.dat_o),
.wb_dat_o(U_ep_wb.master.dat_i),
.wb_ack_o (U_ep_wb.master.ack)
);
initial begin
CWishboneAccessor ep_acc;
CSimDrv_WR_Endpoint ep_drv;
U_ep_src.settings.gen_random_throttling = 0;
U_ep_snk.settings.gen_random_stalls = 0;
@(posedge rst_n_i);
repeat(100) @(posedge clk_sys_i);
ep_acc = U_ep_wb.get_accessor();
ep_drv = new (ep_acc, 0);
ep_drv.init();
from_port[i] = new (U_ep_snk.get_accessor());
to_port[i] = new (U_ep_src.get_accessor());
end
end // for (i=0; i<g_num_ports; i++)
endgenerate
generate
genvar j;
for(j=0;j<g_num_ports;j++) begin
assign rbclk[j] = clk_ref_phys[j];
assign td[18 * j + 15 : 18 * j] = phys_out[j].tx_data;
assign td[18 * j + 17 : 18 * j + 16] = phys_out[j].tx_k;
assign phys_in[j].ref_clk = clk_ref_phys[j];
assign phys_in[j].rx_data = rd[18 * j + 15 : 18 * j];
assign phys_in[j].rx_k = rd[18 * j + 17 : 18 * j + 16];
assign phys_in[j].rx_clk = clk_ref_i;
assign phys_in[j].tx_enc_err = 0;
assign phys_in[j].rx_enc_err = 0;
always@(posedge clk_ref_i) begin : gen_disparity
if(phys_out[j].rst)
phys_in[j].tx_disparity = 0;
else
phys_in[j].tx_disparity = f_next_8b10b_disparity16
(
phys_in[j].tx_disparity,
phys_out[j].tx_k,
phys_out[j].tx_data);
end
end
endgenerate
scb_top_sim
#(
.g_num_ports(g_num_ports)
)
U_Top
(
.sys_rst_n_i ( rst_n_i),
.clk_startup_i ( clk_sys_i),
.clk_ref_i ( clk_ref_i),
.clk_dmtd_i ( clk_ref_i),
.clk_sys_i ( clk_sys_i),
.wb_adr_i ( cpu.master.adr),
.wb_dat_i ( cpu.master.dat_o),
.wb_dat_o ( cpu.master.dat_i),
.wb_cyc_i ( cpu.master.cyc),
.wb_sel_i ( cpu.master.sel),
.wb_stb_i ( cpu.master.stb),
.wb_we_i ( cpu.master.we),
.wb_ack_o ( cpu.master.ack),
.wb_stall_o ( cpu.master.stall),
.wb_irq_o ( cpu_irq ),
.pps_i ( 1'b0 ),
// .pps_o ( pps_o),
// .dac_helper_sync_n_o ( dac_helper_sync_n_o),
// .dac_helper_sclk_o ( dac_helper_sclk_o),
// .dac_helper_data_o ( dac_helper_data_o),
// .dac_main_sync_n_o ( dac_main_sync_n_o),
// .dac_main_sclk_o ( dac_main_sclk_o),
// .dac_main_data_o ( dac_main_data_o),
// .pll_status_i ( pll_status_i),
// .pll_mosi_o ( pll_mosi_o),
// .pll_miso_i ( pll_miso_i),
// .pll_sck_o ( pll_sck_o),
// .pll_cs_n_o ( pll_cs_n_o),
// .pll_sync_n_o ( pll_sync_n_o),
// .pll_reset_n_o ( pll_reset_n_o),
// .uart_txd_o ( uart_txd_o),
// .uart_rxd_i ( uart_rxd_i),
// .clk_en_o ( clk_en_o),
// .clk_sel_o ( clk_sel_o),
.td_o ( rd),
.rd_i ( td),
.rbclk_i ( rbclk)
// .led_link_o ( led_link_o),
// .led_act_o ( led_act_o);
);
endmodule // scb_top_sim_svwrap
`ifndef __SIMDRV_WR_ENDPOINT_SVH
`define __SIMDRV_WR_ENDPOINT_SVH 1
`timescale 1ns/1ps
`include "simdrv_defs.svh"
`include "endpoint_regs.v"
class CSimDrv_WR_Endpoint;
protected CBusAccessor m_acc;
protected uint64_t m_base;
function new(CBusAccessor acc, uint64_t base);
m_acc = acc;
m_base = base;
endfunction // new
task vlan_egress_untag(int vid, int untag);
m_acc.write(m_base + `ADDR_EP_VCR1, vid | ((untag ? 1: 0) << 12));
endtask // vlan_egress_untag
task pfilter_load_microcode(uint64_t mcode[]);
int i;
for(i=0;i<mcode.size();i++)
begin
m_acc.write(m_base + `ADDR_EP_PFCR1, (mcode[i] & 'hfff) << `EP_PFCR1_MM_DATA_LSB_OFFSET);
m_acc.write(m_base + `ADDR_EP_PFCR0,
(i << `EP_PFCR0_MM_ADDR_OFFSET) |
(((mcode[i] >> 12) & 'hffffff) << `EP_PFCR0_MM_DATA_MSB_OFFSET) |
`EP_PFCR0_MM_WRITE);
end
endtask // pfilter_load_microcde
task pfilter_enable(int enable);
m_acc.write(m_base + `ADDR_EP_PFCR0, enable ? `EP_PFCR0_ENABLE: 0);
endtask // pfilter_enable
`define EP_QMODE_VLAN_DISABLED 3
task init();
m_acc.write(m_base + `ADDR_EP_ECR, `EP_ECR_TX_EN | `EP_ECR_RX_EN);
m_acc.write(m_base + `ADDR_EP_RFCR, 1518 << `EP_RFCR_MRU_OFFSET);
m_acc.write(m_base + `ADDR_EP_VCR0, `EP_QMODE_VLAN_DISABLED << `EP_VCR0_QMODE_OFFSET);
m_acc.write(m_base + `ADDR_EP_TSCR, `EP_TSCR_EN_RXTS | `EP_TSCR_EN_TXTS);
endtask // init
task automatic mdio_read(int addr, output int val);
uint64_t rval;
m_acc.write(m_base + `ADDR_EP_MDIO_CR, (addr>>2) << 16, 4);
while(1)begin
m_acc.read(m_base + `ADDR_EP_MDIO_ASR, rval, 4);
if(rval & 'h80000000) begin
val = rval & 'hffff;
return;
end
end
endtask // mdio_read
task automatic mdio_write(int addr,int val);
uint64_t rval;
m_acc.write(m_base+`ADDR_EP_MDIO_CR, ((addr>>2) << 16) | `EP_MDIO_CR_RW | val);
while(1)begin
#8ns;
m_acc.read(m_base+`ADDR_EP_MDIO_ASR, rval);
if(rval & 'h80000000)
return;
end
endtask // automatic
task automatic check_link(ref int up);
reg[31:0] rval;
mdio_read(m_base + `ADDR_MDIO_MSR, rval);
up= (rval & `MDIO_MSR_LSTATUS) ? 1 : 0;
endtask // check_link
endclass // CSimDrv_WR_Endpoint
`endif // `ifndef __SIMDRV_WR_ENDPOINT_SVH
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