?? can_testbench.v
字號:
end
for (i=0; i<64; i=i+1)
begin
can_testbench.i_can_top.i_can_bsp.i_can_fifo.fifo[i] = 0;
end
$display("(%0t) Fifo initialized", $time);
end
endtask
*/
/*
task read_overrun_info;
input [4:0] start_addr;
input [4:0] end_addr;
integer i;
begin
for (i=start_addr; i<=end_addr; i=i+1)
begin
$display("len[0x%0x]=0x%0x", i, can_testbench.i_can_top.i_can_bsp.i_can_fifo.length_info[i]);
$display("overrun[0x%0x]=0x%0x\n", i, can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[i]);
end
end
endtask
*/
task fifo_info; // Displaying how many packets and how many bytes are in fifo. Not working when wr_info_pointer is smaller than rd_info_pointer.
begin
$display("(%0t) Currently %0d bytes in fifo (%0d packets)", $time, can_testbench.i_can_top.i_can_bsp.i_can_fifo.fifo_cnt,
(can_testbench.i_can_top.i_can_bsp.i_can_fifo.wr_info_pointer - can_testbench.i_can_top.i_can_bsp.i_can_fifo.rd_info_pointer));
end
endtask
task read_register;
input [7:0] reg_addr;
`ifdef CAN_WISHBONE_IF
begin
wait (wb_free);
wb_free = 0;
@ (posedge wb_clk_i);
#1;
cs_can = 1;
wb_adr_i = reg_addr;
wb_cyc_i = 1;
wb_stb_i = 1;
wb_we_i = 0;
wait (wb_ack_o);
$display("(%0t) Reading register [%0d] = 0x%0x", $time, wb_adr_i, wb_dat_o);
@ (posedge wb_clk_i);
#1;
wb_adr_i = 'hz;
wb_cyc_i = 0;
wb_stb_i = 0;
wb_we_i = 'hz;
cs_can = 0;
wb_free = 1;
end
`else
begin
wait (port_free);
port_free = 0;
@ (posedge clk);
#1;
cs_can = 1;
@ (negedge clk);
#1;
ale_i = 1;
port_0_en = 1;
port_0_o = reg_addr;
@ (negedge clk);
#1;
ale_i = 0;
#90; // 73 - 103 ns
port_0_en = 0;
rd_i = 1;
#158;
$display("(%0t) Reading register [%0d] = 0x%0x", $time, can_testbench.i_can_top.addr_latched, port_0_i);
#1;
rd_i = 0;
cs_can = 0;
port_free = 1;
end
`endif
endtask
task write_register;
input [7:0] reg_addr;
input [7:0] reg_data;
`ifdef CAN_WISHBONE_IF
begin
wait (wb_free);
wb_free = 0;
@ (posedge wb_clk_i);
#1;
cs_can = 1;
wb_adr_i = reg_addr;
wb_dat_i = reg_data;
wb_cyc_i = 1;
wb_stb_i = 1;
wb_we_i = 1;
wait (wb_ack_o);
@ (posedge wb_clk_i);
#1;
wb_adr_i = 'hz;
wb_dat_i = 'hz;
wb_cyc_i = 0;
wb_stb_i = 0;
wb_we_i = 'hz;
cs_can = 0;
wb_free = 1;
end
`else
begin
wait (port_free);
port_free = 0;
@ (posedge clk);
#1;
cs_can = 1;
@ (negedge clk);
#1;
ale_i = 1;
port_0_en = 1;
port_0_o = reg_addr;
@ (negedge clk);
#1;
ale_i = 0;
#90; // 73 - 103 ns
port_0_o = reg_data;
wr_i = 1;
#158;
wr_i = 0;
port_0_en = 0;
cs_can = 0;
port_free = 1;
end
`endif
endtask
task read_receive_buffer;
integer i;
begin
$display("\n\n(%0t)", $time);
if(extended_mode) // Extended mode
begin
for (i=8'd16; i<=8'd28; i=i+1)
read_register(i);
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun)
$display("\nWARNING: Above packet was received with overrun.");
end
else
begin
for (i=8'd20; i<=8'd29; i=i+1)
read_register(i);
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun)
$display("\nWARNING: Above packet was received with overrun.");
end
end
endtask
task release_rx_buffer_command;
begin
write_register(8'd1, 8'h4);
$display("(%0t) Rx buffer released.", $time);
end
endtask
task tx_request_command;
begin
write_register(8'd1, 8'h1);
$display("(%0t) Tx requested.", $time);
end
endtask
task tx_abort_command;
begin
write_register(8'd1, 8'h2);
$display("(%0t) Tx abort requested.", $time);
end
endtask
task clear_data_overrun_command;
begin
write_register(8'd1, 8'h8);
$display("(%0t) Data overrun cleared.", $time);
end
endtask
task self_reception_request_command;
begin
write_register(8'd1, 8'h10);
$display("(%0t) Self reception requested.", $time);
end
endtask
task test_synchronization;
begin
// Hard synchronization
#1 rx=0;
repeat (2*BRP) @ (posedge clk);
repeat (8*BRP) @ (posedge clk);
#1 rx=1;
repeat (10*BRP) @ (posedge clk);
// Resynchronization on time
#1 rx=0;
repeat (10*BRP) @ (posedge clk);
#1 rx=1;
repeat (10*BRP) @ (posedge clk);
// Resynchronization late
repeat (BRP) @ (posedge clk);
repeat (BRP) @ (posedge clk);
#1 rx=0;
repeat (10*BRP) @ (posedge clk);
#1 rx=1;
// Resynchronization early
repeat (8*BRP) @ (posedge clk); // two frames too early
#1 rx=0;
repeat (10*BRP) @ (posedge clk);
#1 rx=1;
repeat (10*BRP) @ (posedge clk);
end
endtask
task send_bit;
input bit;
integer cnt;
begin
#1 rx=bit;
repeat ((`CAN_TIMING1_TSEG1 + `CAN_TIMING1_TSEG2 + 3)*BRP) @ (posedge clk);
end
endtask
task receive_frame; // CAN IP core receives frames
input mode;
input remote_trans_req;
input [28:0] id;
input [3:0] length;
input [14:0] crc;
reg [117:0] data;
reg previous_bit;
reg stuff;
reg tmp;
reg arbitration_lost;
integer pointer;
integer cnt;
integer total_bits;
integer stuff_cnt;
begin
stuff_cnt = 1;
stuff = 0;
if(mode) // Extended format
data = {id[28:18], 1'b1, 1'b1, id[17:0], remote_trans_req, 2'h0, length};
else // Standard format
data = {id[10:0], remote_trans_req, 1'b0, 1'b0, length};
if (~remote_trans_req)
begin
if(length) // Send data if length is > 0
begin
for (cnt=1; cnt<=(2*length); cnt=cnt+1) // data (we are sending nibbles)
data = {data[113:0], cnt[3:0]};
end
end
// Adding CRC
data = {data[104:0], crc[14:0]};
// Calculating pointer that points to the bit that will be send
if (remote_trans_req)
begin
if(mode) // Extended format
pointer = 52;
else // Standard format
pointer = 32;
end
else
begin
if(mode) // Extended format
pointer = 52 + 8 * length;
else // Standard format
pointer = 32 + 8 * length;
end
// This is how many bits we need to shift
total_bits = pointer;
// Waiting until previous msg is finished before sending another one
if (arbitration_lost) // Arbitration lost. Another node is transmitting. We have to wait until it is finished.
wait ( (~can_testbench.i_can_top.i_can_bsp.error_frame) &
(~can_testbench.i_can_top.i_can_bsp.rx_inter ) &
(~can_testbench.i_can_top.i_can_bsp.tx_state )
);
else // We were transmitter of the previous frame. No need to wait for another node to finish transmission.
wait ( (~can_testbench.i_can_top.i_can_bsp.error_frame) &
(~can_testbench.i_can_top.i_can_bsp.rx_inter )
);
arbitration_lost = 0;
send_bit(0); // SOF
previous_bit = 0;
fork
begin
for (cnt=0; cnt<=total_bits; cnt=cnt+1)
begin
if (stuff_cnt == 5)
begin
stuff_cnt = 1;
total_bits = total_bits + 1;
stuff = 1;
tmp = ~data[pointer+1];
send_bit(~data[pointer+1]);
previous_bit = ~data[pointer+1];
end
else
begin
if (data[pointer] == previous_bit)
stuff_cnt <= stuff_cnt + 1;
else
stuff_cnt <= 1;
stuff = 0;
tmp = data[pointer];
send_bit(data[pointer]);
previous_bit = data[pointer];
pointer = pointer - 1;
end
if (arbitration_lost)
cnt=total_bits+1; // Exit the for loop
end
// Nothing send after the data (just recessive bit)
repeat (13) send_bit(1); // CRC delimiter + ack + ack delimiter + EOF + intermission= 1 + 1 + 1 + 7 + 3
end
begin
while (mode ? (cnt<32) : (cnt<12))
begin
#1 wait (can_testbench.i_can_top.sample_point);
if (mode)
begin
if (cnt<32 & tmp & (~rx_and_tx))
begin
arbitration_lost = 1;
rx = 1; // Only recessive is send from now on.
end
end
else
begin
if (cnt<12 & tmp & (~rx_and_tx))
begin
arbitration_lost = 1;
rx = 1; // Only recessive is send from now on.
end
end
end
end
join
end
endtask
// State machine monitor (btl)
always @ (posedge clk)
begin
if(can_testbench.i_can_top.i_can_btl.go_sync & can_testbench.i_can_top.i_can_btl.go_seg1 | can_testbench.i_can_top.i_can_btl.go_sync & can_testbench.i_can_top.i_can_btl.go_seg2 |
can_testbench.i_can_top.i_can_btl.go_seg1 & can_testbench.i_can_top.i_can_btl.go_seg2)
begin
$display("(%0t) ERROR multiple go_sync, go_seg1 or go_seg2 occurance\n\n", $time);
#1000;
$stop;
end
if(can_testbench.i_can_top.i_can_btl.sync & can_testbench.i_can_top.i_can_btl.seg1 | can_testbench.i_can_top.i_can_btl.sync & can_testbench.i_can_top.i_can_btl.seg2 |
can_testbench.i_can_top.i_can_btl.seg1 & can_testbench.i_can_top.i_can_btl.seg2)
begin
$display("(%0t) ERROR multiple sync, seg1 or seg2 occurance\n\n", $time);
#1000;
$stop;
end
end
/* stuff_error monitor (bsp)
always @ (posedge clk)
begin
if(can_testbench.i_can_top.i_can_bsp.stuff_error)
begin
$display("\n\n(%0t) Stuff error occured in can_bsp.v file\n\n", $time);
$stop; After everything is finished add another condition (something like & (~idle)) and enable stop
end
end
*/
//
// CRC monitor (used until proper CRC generation is used in testbench
always @ (posedge clk)
begin
if (can_testbench.i_can_top.i_can_bsp.rx_ack &
can_testbench.i_can_top.i_can_bsp.sample_point &
can_testbench.i_can_top.i_can_bsp.crc_err
)
$display("*E (%0t) ERROR: CRC error (Calculated crc = 0x%0x, crc_in = 0x%0x)", $time, can_testbench.i_can_top.i_can_bsp.calculated_crc, can_testbench.i_can_top.i_can_bsp.crc_in);
end
/*
// overrun monitor
always @ (posedge clk)
begin
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.wr & can_testbench.i_can_top.i_can_bsp.i_can_fifo.fifo_full)
$display("(%0t)overrun", $time);
end
*/
// form error monitor
always @ (posedge clk)
begin
if (can_testbench.i_can_top.i_can_bsp.form_err)
$display("*E (%0t) ERROR: form_error", $time);
end
// acknowledge error monitor
always @ (posedge clk)
begin
if (can_testbench.i_can_top.i_can_bsp.ack_err)
$display("*E (%0t) ERROR: acknowledge_error", $time);
end
/*
// bit error monitor
always @ (posedge clk)
begin
if (can_testbench.i_can_top.i_can_bsp.bit_err)
$display("*E (%0t) ERROR: bit_error", $time);
end
*/
endmodule
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -