Newer
Older
/* Crude wrapper for Gennum-provided GN4124x BFM. Supports only single CSR reads/writes so far. */
`ifndef __GN4124_BFM_SVH
`define __GN4124_BFM_SVH 1
`include "simdrv_defs.svh"
interface IGN4124PCIMaster;

Dimitris Lampridis
committed
int cmd_str_int[256];
reg cmd_req = 0;
wire cmd_ack;
reg internal_rstn = 0;
wire lclk_p, lclk_n, l2p_clk_p, l2p_clk_n, p2l_clk_p, p2l_clk_n;
wire [15:0] l2p_data, p2l_data;
wire l2p_dframe, l2p_valid, l2p_edb;
wire p2l_dframe, p2l_valid, p2l_rdy;

Dimitris Lampridis
committed
wire [1:0] l_wr_rdy, p_rd_d_rdy;
wire [1:0] p_wr_req, p_wr_rdy, vc_rdy;
wire l2p_rdy, tx_error, rx_error;
wire [15:0] gpio;

Dimitris Lampridis
committed
// Local bus to Gennum
modport L2P
(
input l2p_clk_n,
input l2p_clk_p,
input l2p_data,
input l2p_dframe,
input l2p_valid,
input l2p_edb,

Dimitris Lampridis
committed
output l_wr_rdy,

Dimitris Lampridis
committed
output l2p_rdy,

Dimitris Lampridis
committed

Dimitris Lampridis
committed
modport P2L
(
output p2l_clk_p,
output p2l_clk_n,
output p2l_dframe,
output p2l_data,
output p2l_valid,
input p2l_rdy,
output p_wr_req,
input p_wr_rdy,
input rx_error,
output vc_rdy
);
wire rst_n;

Dimitris Lampridis
committed
modport SYS
(
output lclk_p,
output lclk_n,
output rst_n,
inout gpio);

Dimitris Lampridis
committed
wire [31:0] cmd_rddata;
wire cmd_rddata_valid;

Dimitris Lampridis
committed
GN412X_BFM

Dimitris Lampridis
committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
.CMD_INT (cmd_str_int),
.CMD_REQ (cmd_req),
.CMD_ACK (cmd_ack),
.CMD_CLOCK_EN (1'b1),
.CMD_RD_DATA (cmd_rddata),
.CMD_RD_DATA_VALID (cmd_rddata_valid),
.RSTINn (internal_rstn),
.RSTOUT18n (),
.RSTOUT33n (rst_n),
.LCLK (lclk_p),
.LCLKn (lclk_n),
.L2P_CLKp (l2p_clk_p),
.L2P_CLKn (l2p_clk_n),
.L2P_DATA (l2p_data),
.L2P_DFRAME (l2p_dframe),
.L2P_VALID (l2p_valid),
.L2P_EDB (l2p_edb),
.L_WR_RDY (l_wr_rdy),
.P_RD_D_RDY (p_rd_d_rdy),
.L2P_RDY (l2p_rdy),
.TX_ERROR (tx_error),
.P2L_CLKp (p2l_clk_p),
.P2L_CLKn (p2l_clk_n),
.P2L_DATA (p2l_data),
.P2L_DFRAME (p2l_dframe),
.P2L_VALID (p2l_valid),
.P2L_RDY (p2l_rdy),
.P_WR_REQ (p_wr_req),
.P_WR_RDY (p_wr_rdy),
.RX_ERROR (rx_error),
.VC_RDY (vc_rdy),
.GPIO (gpio)
);

Dimitris Lampridis
committed
task send_cmd(string cmd);
int i;
string cmd_2;
$sformat(cmd_2, "%-1d %s", line_no++, cmd);

Dimitris Lampridis
committed
//$display("SendCmd '%s'", cmd_2);

Dimitris Lampridis
committed
cmd_str_int[i] = int'(cmd_2[i]);

Dimitris Lampridis
committed
#10ns;
cmd_req = 1;
while(!cmd_ack) #1ns;
cmd_req = 0;
while(cmd_ack) #1ns;
#10ns;

Dimitris Lampridis
committed
endtask // send_cmd
bit ready = 0;

Dimitris Lampridis
committed
task init();
#100ns;
internal_rstn <= 1;
#100ns;

Dimitris Lampridis
committed
send_cmd("init");
send_cmd("reset %d16");
send_cmd("bar 0 FF00000000000000 08000000 0 7 0");
send_cmd("bfm_bar 0 0000000040000000 20000000");
send_cmd("bfm_bar 1 0000000020000000 20000000");
send_cmd("wait %d64");
ready = 1;

Dimitris Lampridis
committed
// send_cmd("wr FF000000000A0004 F 007C0270");
// send_cmd("rd FF000000000A0004 F");
endtask // init
initial init();
task automatic readback(ref uint64_t value);
@(posedge cmd_rddata_valid);
value = cmd_rddata;
@(negedge cmd_rddata_valid);
endtask // readback

Dimitris Lampridis
committed

Dimitris Lampridis
committed
task host_mem_write(uint64_t addr, uint64_t data);
string cmd;
$sformat(cmd,"wr 00000000%08X F %08X", 'h20000000 + addr, data);
send_cmd(cmd);
endtask // host_mem_write
task automatic host_mem_read(uint64_t addr, ref uint64_t data);
string cmd;
$sformat(cmd,"rd 00000000%08X F", 'h20000000 + addr);
fork
send_cmd(cmd);
readback(data);
join
endtask // host_mem_read

Dimitris Lampridis
committed
class CBusAccessor_Gennum extends CBusAccessor;
function new();

Dimitris Lampridis
committed
endfunction // new
task writem(uint64_t addr[], uint64_t data[], input int size, ref int result);
string cmd;
int i;
if(size != 4)

Dimitris Lampridis
committed
size = 4;

Dimitris Lampridis
committed
begin
$sformat(cmd,"wr FF000000%08X F %08X", addr[i], data[i]);
send_cmd(cmd);
end

Dimitris Lampridis
committed
task readm(uint64_t addr[], ref uint64_t data[], input int size, ref int result);
string cmd;
int i;
uint64_t tmp;

Dimitris Lampridis
committed

Dimitris Lampridis
committed
size = 4;

Dimitris Lampridis
committed
begin
$sformat(cmd,"rd FF000000%08X F", addr[i]);
fork
send_cmd(cmd);
readback(tmp);
join
data[i] = tmp;
end

Dimitris Lampridis
committed
endclass // CBusAccessor_Gennum
function CBusAccessor get_accessor();
automatic CBusAccessor_Gennum g = new();

Dimitris Lampridis
committed
endinterface
/* Helper macro for wiring Gennum-Xilinx ports in spec_top */
`define GENNUM_WIRE_SPEC_PINS(IF_NAME) \

Dimitris Lampridis
committed
.L_RST_N (IF_NAME.rst_n),\
.L_CLKp (IF_NAME.lclk_p),\
.L_CLKn (IF_NAME.lclk_n),\
.p2l_clkp (IF_NAME.p2l_clk_p),\
.p2l_clkn (IF_NAME.p2l_clk_n),\
.p2l_data (IF_NAME.p2l_data),\
.p2l_dframe (IF_NAME.p2l_dframe),\
.p2l_valid (IF_NAME.p2l_valid),\
.p2l_rdy (IF_NAME.p2l_rdy),\
.p_wr_req (IF_NAME.p_wr_req),\
.p_wr_rdy (IF_NAME.p_wr_rdy),\
.rx_error (IF_NAME.rx_error),\
.l2p_clkp (IF_NAME.l2p_clk_p),\
.l2p_clkn (IF_NAME.l2p_clk_n),\
.l2p_data (IF_NAME.l2p_data),\
.l2p_dframe (IF_NAME.l2p_dframe),\
.l2p_valid (IF_NAME.l2p_valid),\
.l2p_edb (IF_NAME.l2p_edb),\
.l2p_rdy (IF_NAME.l2p_rdy),\
.l_wr_rdy (IF_NAME.l_wr_rdy),\
.p_rd_d_rdy (IF_NAME.p_rd_d_rdy),\
.tx_error (IF_NAME.tx_error),\
.vc_rdy (IF_NAME.vc_rdy)
//the same as above but with names of the top SPEC entity that stick to naming conventions
`define GENNUM_WIRE_SPEC_PINS_WITH_PROPER_NAMING(IF_NAME) \

Dimitris Lampridis
committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
.l_rst_n_i (IF_NAME.rst_n),\
.l_clk_p_i (IF_NAME.lclk_p),\
.l_clk_n_i (IF_NAME.lclk_n),\
.p2l_clk_p_i (IF_NAME.p2l_clk_p),\
.p2l_clk_n_i (IF_NAME.p2l_clk_n),\
.p2l_data_i (IF_NAME.p2l_data),\
.p2l_dframe_i (IF_NAME.p2l_dframe),\
.p2l_valid_i (IF_NAME.p2l_valid),\
.p2l_rdy_o (IF_NAME.p2l_rdy),\
.p_wr_req_i (IF_NAME.p_wr_req),\
.p_wr_rdy_o (IF_NAME.p_wr_rdy),\
.l_rx_error_o (IF_NAME.rx_error),\
.l2p_clk_p_o (IF_NAME.l2p_clk_p),\
.l2p_clk_n_o (IF_NAME.l2p_clk_n),\
.l2p_data_o (IF_NAME.l2p_data),\
.l2p_dframe_o (IF_NAME.l2p_dframe),\
.l2p_valid_o (IF_NAME.l2p_valid),\
.l2p_edb_o (IF_NAME.l2p_edb),\
.l2p_rdy_i (IF_NAME.l2p_rdy),\
.l_wr_rdy_i (IF_NAME.l_wr_rdy),\
.p_rd_d_rdy_i (IF_NAME.p_rd_d_rdy),\
.tx_error_i (IF_NAME.tx_error),\
.vc_rdy_i (IF_NAME.vc_rdy)
//the same as above but with names matching those of the BTrain SPEC reference design
`define GENNUM_WIRE_SPEC_BTRAIN_REF(IF_NAME) \
.gn_rst_n_i (IF_NAME.rst_n),\
.gn_p2l_clk_p_i (IF_NAME.p2l_clk_p),\
.gn_p2l_clk_n_i (IF_NAME.p2l_clk_n),\
.gn_p2l_rdy_o (IF_NAME.p2l_rdy),\
.gn_p2l_dframe_i (IF_NAME.p2l_dframe),\
.gn_p2l_valid_i (IF_NAME.p2l_valid),\
.gn_p2l_data_i (IF_NAME.p2l_data),\
.gn_p_wr_req_i (IF_NAME.p_wr_req),\
.gn_p_wr_rdy_o (IF_NAME.p_wr_rdy),\
.gn_rx_error_o (IF_NAME.rx_error),\
.gn_l2p_clkn_o (IF_NAME.l2p_clk_n),\
.gn_l2p_clkp_o (IF_NAME.l2p_clk_p),\
.gn_l2p_dframe_o (IF_NAME.l2p_dframe),\
.gn_l2p_valid_o (IF_NAME.l2p_valid),\
.gn_l2p_edb_o (IF_NAME.l2p_edb),\
.gn_l2p_data_o (IF_NAME.l2p_data),\
.gn_l2p_rdy_i (IF_NAME.l2p_rdy),\
.gn_l_wr_rdy_i (IF_NAME.l_wr_rdy),\
.gn_p_rd_d_rdy_i (IF_NAME.p_rd_d_rdy),\
.gn_tx_error_i (IF_NAME.tx_error),\
.gn_vc_rdy_i (IF_NAME.vc_rdy),\
.gn_gpio_b ()

Dimitris Lampridis
committed