//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// can_testbench.v ////
|
//// can_testbench.v ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// This file is part of the CAN Protocol Controller ////
|
//// This file is part of the CAN Protocol Controller ////
|
//// http://www.opencores.org/projects/can/ ////
|
//// http://www.opencores.org/projects/can/ ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// Igor Mohor ////
|
//// Igor Mohor ////
|
//// igorm@opencores.org ////
|
//// igorm@opencores.org ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// All additional information is available in the README.txt ////
|
//// All additional information is available in the README.txt ////
|
//// file. ////
|
//// file. ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2002, 2003 Authors ////
|
//// Copyright (C) 2002, 2003 Authors ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//// The CAN protocol is developed by Robert Bosch GmbH and ////
|
//// The CAN protocol is developed by Robert Bosch GmbH and ////
|
//// protected by patents. Anybody who wants to implement this ////
|
//// protected by patents. Anybody who wants to implement this ////
|
//// CAN IP core on silicon has to obtain a CAN protocol license ////
|
//// CAN IP core on silicon has to obtain a CAN protocol license ////
|
//// from Bosch. ////
|
//// from Bosch. ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.24 2003/02/14 20:16:53 mohor
|
|
// Several registers added. Not finished, yet.
|
|
//
|
// Revision 1.23 2003/02/12 14:28:30 mohor
|
// Revision 1.23 2003/02/12 14:28:30 mohor
|
// Errors monitoring improved. arbitration_lost improved.
|
// Errors monitoring improved. arbitration_lost improved.
|
//
|
//
|
// Revision 1.22 2003/02/11 00:57:19 mohor
|
// Revision 1.22 2003/02/11 00:57:19 mohor
|
// Wishbone interface added.
|
// Wishbone interface added.
|
//
|
//
|
// Revision 1.21 2003/02/09 18:40:23 mohor
|
// Revision 1.21 2003/02/09 18:40:23 mohor
|
// Overload fixed. Hard synchronization also enabled at the last bit of
|
// Overload fixed. Hard synchronization also enabled at the last bit of
|
// interframe.
|
// interframe.
|
//
|
//
|
// Revision 1.20 2003/02/09 02:24:11 mohor
|
// Revision 1.20 2003/02/09 02:24:11 mohor
|
// Bosch license warning added. Error counters finished. Overload frames
|
// Bosch license warning added. Error counters finished. Overload frames
|
// still need to be fixed.
|
// still need to be fixed.
|
//
|
//
|
// Revision 1.19 2003/02/04 17:24:33 mohor
|
// Revision 1.19 2003/02/04 17:24:33 mohor
|
// Backup.
|
// Backup.
|
//
|
//
|
// Revision 1.18 2003/02/04 14:34:45 mohor
|
// Revision 1.18 2003/02/04 14:34:45 mohor
|
// *** empty log message ***
|
// *** empty log message ***
|
//
|
//
|
// Revision 1.17 2003/01/31 01:13:31 mohor
|
// Revision 1.17 2003/01/31 01:13:31 mohor
|
// backup.
|
// backup.
|
//
|
//
|
// Revision 1.16 2003/01/16 13:36:14 mohor
|
// Revision 1.16 2003/01/16 13:36:14 mohor
|
// Form error supported. When receiving messages, last bit of the end-of-frame
|
// Form error supported. When receiving messages, last bit of the end-of-frame
|
// does not generate form error. Receiver goes to the idle mode one bit sooner.
|
// does not generate form error. Receiver goes to the idle mode one bit sooner.
|
// (CAN specification ver 2.0, part B, page 57).
|
// (CAN specification ver 2.0, part B, page 57).
|
//
|
//
|
// Revision 1.15 2003/01/15 21:05:06 mohor
|
// Revision 1.15 2003/01/15 21:05:06 mohor
|
// CRC checking fixed (when bitstuff occurs at the end of a CRC sequence).
|
// CRC checking fixed (when bitstuff occurs at the end of a CRC sequence).
|
//
|
//
|
// Revision 1.14 2003/01/15 14:40:16 mohor
|
// Revision 1.14 2003/01/15 14:40:16 mohor
|
// RX state machine fixed to receive "remote request" frames correctly. No
|
// RX state machine fixed to receive "remote request" frames correctly. No
|
// data bytes are written to fifo when such frames are received.
|
// data bytes are written to fifo when such frames are received.
|
//
|
//
|
// Revision 1.13 2003/01/15 13:16:42 mohor
|
// Revision 1.13 2003/01/15 13:16:42 mohor
|
// When a frame with "remote request" is received, no data is stored to
|
// When a frame with "remote request" is received, no data is stored to
|
// fifo, just the frame information (identifier, ...). Data length that
|
// fifo, just the frame information (identifier, ...). Data length that
|
// is stored is the received data length and not the actual data length
|
// is stored is the received data length and not the actual data length
|
// that is stored to fifo.
|
// that is stored to fifo.
|
//
|
//
|
// Revision 1.12 2003/01/14 17:25:03 mohor
|
// Revision 1.12 2003/01/14 17:25:03 mohor
|
// Addresses corrected to decimal values (previously hex).
|
// Addresses corrected to decimal values (previously hex).
|
//
|
//
|
// Revision 1.11 2003/01/14 12:19:29 mohor
|
// Revision 1.11 2003/01/14 12:19:29 mohor
|
// rx_fifo is now working.
|
// rx_fifo is now working.
|
//
|
//
|
// Revision 1.10 2003/01/10 17:51:28 mohor
|
// Revision 1.10 2003/01/10 17:51:28 mohor
|
// Temporary version (backup).
|
// Temporary version (backup).
|
//
|
//
|
// Revision 1.9 2003/01/09 21:54:39 mohor
|
// Revision 1.9 2003/01/09 21:54:39 mohor
|
// rx fifo added. Not 100 % verified, yet.
|
// rx fifo added. Not 100 % verified, yet.
|
//
|
//
|
// Revision 1.8 2003/01/08 02:09:43 mohor
|
// Revision 1.8 2003/01/08 02:09:43 mohor
|
// Acceptance filter added.
|
// Acceptance filter added.
|
//
|
//
|
// Revision 1.7 2002/12/28 04:13:53 mohor
|
// Revision 1.7 2002/12/28 04:13:53 mohor
|
// Backup version.
|
// Backup version.
|
//
|
//
|
// Revision 1.6 2002/12/27 00:12:48 mohor
|
// Revision 1.6 2002/12/27 00:12:48 mohor
|
// Header changed, testbench improved to send a frame (crc still missing).
|
// Header changed, testbench improved to send a frame (crc still missing).
|
//
|
//
|
// Revision 1.5 2002/12/26 16:00:29 mohor
|
// Revision 1.5 2002/12/26 16:00:29 mohor
|
// Testbench define file added. Clock divider register added.
|
// Testbench define file added. Clock divider register added.
|
//
|
//
|
// Revision 1.4 2002/12/26 01:33:01 mohor
|
// Revision 1.4 2002/12/26 01:33:01 mohor
|
// Tripple sampling supported.
|
// Tripple sampling supported.
|
//
|
//
|
// Revision 1.3 2002/12/25 23:44:12 mohor
|
// Revision 1.3 2002/12/25 23:44:12 mohor
|
// Commented lines removed.
|
// Commented lines removed.
|
//
|
//
|
// Revision 1.2 2002/12/25 14:16:54 mohor
|
// Revision 1.2 2002/12/25 14:16:54 mohor
|
// Synchronization working.
|
// Synchronization working.
|
//
|
//
|
// Revision 1.1.1.1 2002/12/20 16:39:21 mohor
|
// Revision 1.1.1.1 2002/12/20 16:39:21 mohor
|
// Initial
|
// Initial
|
//
|
//
|
//
|
//
|
//
|
//
|
|
|
// synopsys translate_off
|
// synopsys translate_off
|
`include "timescale.v"
|
`include "timescale.v"
|
// synopsys translate_on
|
// synopsys translate_on
|
`include "can_defines.v"
|
`include "can_defines.v"
|
`include "can_testbench_defines.v"
|
`include "can_testbench_defines.v"
|
|
|
module can_testbench();
|
module can_testbench();
|
|
|
|
|
|
|
parameter Tp = 1;
|
parameter Tp = 1;
|
parameter BRP = 2*(`CAN_TIMING0_BRP + 1);
|
parameter BRP = 2*(`CAN_TIMING0_BRP + 1);
|
|
|
|
|
|
|
reg wb_clk_i;
|
reg wb_clk_i;
|
reg wb_rst_i;
|
reg wb_rst_i;
|
reg [7:0] wb_dat_i;
|
reg [7:0] wb_dat_i;
|
wire [7:0] wb_dat_o;
|
wire [7:0] wb_dat_o;
|
reg wb_cyc_i;
|
reg wb_cyc_i;
|
reg wb_stb_i;
|
reg wb_stb_i;
|
|
|
reg wb_we_i;
|
reg wb_we_i;
|
reg [7:0] wb_adr_i;
|
reg [7:0] wb_adr_i;
|
reg clk;
|
reg clk;
|
reg rx;
|
reg rx;
|
wire tx;
|
wire tx;
|
wire tx_oen;
|
wire tx_oen;
|
wire wb_ack_o;
|
wire wb_ack_o;
|
wire irq;
|
wire irq;
|
|
|
wire tx_3st;
|
wire tx_3st;
|
wire rx_and_tx;
|
wire rx_and_tx;
|
|
|
integer start_tb;
|
integer start_tb;
|
reg [7:0] tmp_data;
|
reg [7:0] tmp_data;
|
reg delayed_tx;
|
reg delayed_tx;
|
reg tx_bypassed;
|
reg tx_bypassed;
|
reg wb_free;
|
reg wb_free;
|
|
reg extended_mode;
|
|
|
|
|
|
|
// Instantiate can_top module
|
// Instantiate can_top module
|
can_top i_can_top
|
can_top i_can_top
|
(
|
(
|
.wb_clk_i(wb_clk_i),
|
.wb_clk_i(wb_clk_i),
|
.wb_rst_i(wb_rst_i),
|
.wb_rst_i(wb_rst_i),
|
.wb_dat_i(wb_dat_i),
|
.wb_dat_i(wb_dat_i),
|
.wb_dat_o(wb_dat_o),
|
.wb_dat_o(wb_dat_o),
|
.wb_cyc_i(wb_cyc_i),
|
.wb_cyc_i(wb_cyc_i),
|
.wb_stb_i(wb_stb_i),
|
.wb_stb_i(wb_stb_i),
|
.wb_we_i(wb_we_i),
|
.wb_we_i(wb_we_i),
|
.wb_adr_i(wb_adr_i),
|
.wb_adr_i(wb_adr_i),
|
.wb_ack_o(wb_ack_o),
|
.wb_ack_o(wb_ack_o),
|
.clk(clk),
|
.clk(clk),
|
.rx(rx_and_tx),
|
.rx(rx_and_tx),
|
.tx(tx),
|
.tx(tx),
|
.tx_oen(tx_oen),
|
.tx_oen(tx_oen),
|
.irq(irq)
|
.irq(irq)
|
);
|
);
|
|
|
assign tx_3st = tx_oen? 1'bz : tx;
|
assign tx_3st = tx_oen? 1'bz : tx;
|
|
|
|
|
// Generate wishbone clock signal 10 MHz FIX ME
|
// Generate wishbone clock signal 10 MHz FIX ME
|
initial
|
initial
|
begin
|
begin
|
wb_clk_i=0;
|
wb_clk_i=0;
|
forever #20 wb_clk_i = ~wb_clk_i;
|
forever #20 wb_clk_i = ~wb_clk_i;
|
end
|
end
|
|
|
|
|
// Generate clock signal 24 MHz FIX ME
|
// Generate clock signal 24 MHz FIX ME
|
initial
|
initial
|
begin
|
begin
|
clk=0;
|
clk=0;
|
forever #20 clk = ~clk;
|
forever #20 clk = ~clk;
|
end
|
end
|
|
|
|
|
initial
|
initial
|
begin
|
begin
|
start_tb = 0;
|
start_tb = 0;
|
wb_dat_i = 'hz;
|
wb_dat_i = 'hz;
|
wb_cyc_i = 0;
|
wb_cyc_i = 0;
|
wb_stb_i = 0;
|
wb_stb_i = 0;
|
wb_we_i = 'hz;
|
wb_we_i = 'hz;
|
wb_adr_i = 'hz;
|
wb_adr_i = 'hz;
|
wb_free = 1;
|
wb_free = 1;
|
rx = 1;
|
rx = 1;
|
wb_rst_i = 1;
|
wb_rst_i = 1;
|
|
extended_mode = 0;
|
#200 wb_rst_i = 0;
|
#200 wb_rst_i = 0;
|
#200 initialize_fifo;
|
#200 initialize_fifo;
|
#200 start_tb = 1;
|
#200 start_tb = 1;
|
tx_bypassed = 0;
|
tx_bypassed = 0;
|
end
|
end
|
|
|
|
|
|
|
|
|
// Generating delayed tx signal (CAN transciever delay)
|
// Generating delayed tx signal (CAN transciever delay)
|
always
|
always
|
begin
|
begin
|
wait (tx_3st);
|
wait (tx_3st);
|
repeat (4*BRP) @ (posedge clk); // 4 time quants delay
|
repeat (4*BRP) @ (posedge clk); // 4 time quants delay
|
#1 delayed_tx = tx_3st;
|
#1 delayed_tx = tx_3st;
|
wait (~tx_3st);
|
wait (~tx_3st);
|
repeat (4*BRP) @ (posedge clk); // 4 time quants delay
|
repeat (4*BRP) @ (posedge clk); // 4 time quants delay
|
#1 delayed_tx = tx_3st;
|
#1 delayed_tx = tx_3st;
|
end
|
end
|
|
|
//assign rx_and_tx = rx & delayed_tx; FIX ME !!!
|
//assign rx_and_tx = rx & delayed_tx; FIX ME !!!
|
assign rx_and_tx = rx & (delayed_tx | tx_bypassed);
|
assign rx_and_tx = rx & (delayed_tx | tx_bypassed);
|
|
|
|
|
// Main testbench
|
// Main testbench
|
initial
|
initial
|
begin
|
begin
|
wait(start_tb);
|
wait(start_tb);
|
|
|
// Set bus timing register 0
|
// Set bus timing register 0
|
write_register(8'd6, {`CAN_TIMING0_SJW, `CAN_TIMING0_BRP});
|
write_register(8'd6, {`CAN_TIMING0_SJW, `CAN_TIMING0_BRP});
|
|
|
// Set bus timing register 1
|
// Set bus timing register 1
|
write_register(8'd7, {`CAN_TIMING1_SAM, `CAN_TIMING1_TSEG2, `CAN_TIMING1_TSEG1});
|
write_register(8'd7, {`CAN_TIMING1_SAM, `CAN_TIMING1_TSEG2, `CAN_TIMING1_TSEG1});
|
|
|
|
|
// Set Clock Divider register
|
// Set Clock Divider register
|
write_register(8'd31, {`CAN_CLOCK_DIVIDER_MODE, 7'h0}); // Setting the normal mode (not extended)
|
extended_mode = 1'b0;
|
|
write_register(8'd31, {extended_mode, 7'h0}); // Setting the normal mode (not extended)
|
|
|
|
|
// Set Acceptance Code and Acceptance Mask registers (their address differs for basic and extended mode
|
// Set Acceptance Code and Acceptance Mask registers (their address differs for basic and extended mode
|
if(`CAN_CLOCK_DIVIDER_MODE) // Extended mode
|
/*
|
begin
|
// Set Acceptance Code and Acceptance Mask registers
|
// Set Acceptance Code and Acceptance Mask registers
|
write_register(8'd16, 8'ha6); // acceptance code 0
|
write_register(8'd16, 8'ha6); // acceptance code 0
|
write_register(8'd17, 8'hb0); // acceptance code 1
|
write_register(8'd17, 8'hb0); // acceptance code 1
|
write_register(8'd18, 8'h12); // acceptance code 2
|
write_register(8'd18, 8'h12); // acceptance code 2
|
write_register(8'd19, 8'h30); // acceptance code 3
|
write_register(8'd19, 8'h30); // acceptance code 3
|
write_register(8'd20, 8'h0); // acceptance mask 0
|
write_register(8'd20, 8'h0); // acceptance mask 0
|
write_register(8'd21, 8'h0); // acceptance mask 1
|
write_register(8'd21, 8'h0); // acceptance mask 1
|
write_register(8'd22, 8'h00); // acceptance mask 2
|
write_register(8'd22, 8'h00); // acceptance mask 2
|
write_register(8'd23, 8'h00); // acceptance mask 3
|
write_register(8'd23, 8'h00); // acceptance mask 3
|
*/
|
end
|
|
else
|
|
begin
|
|
// Set Acceptance Code and Acceptance Mask registers
|
// Set Acceptance Code and Acceptance Mask registers
|
// write_register(8'd4, 8'ha6); // acceptance code
|
|
write_register(8'd4, 8'he8); // acceptance code
|
write_register(8'd4, 8'he8); // acceptance code
|
write_register(8'd5, 8'h0f); // acceptance mask
|
write_register(8'd5, 8'h0f); // acceptance mask
|
end
|
|
|
|
#10;
|
#10;
|
repeat (1000) @ (posedge clk);
|
repeat (1000) @ (posedge clk);
|
|
|
// Switch-off reset mode
|
// Switch-off reset mode
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
|
|
repeat (BRP) @ (posedge clk); // At least BRP clocks needed before bus goes to dominant level. Otherwise 1 quant difference is possible
|
repeat (BRP) @ (posedge clk); // At least BRP clocks needed before bus goes to dominant level. Otherwise 1 quant difference is possible
|
// This difference is resynchronized later.
|
// This difference is resynchronized later.
|
|
|
// After exiting the reset mode
|
// After exiting the reset mode
|
repeat (7) send_bit(1); // Sending EOF
|
repeat (7) send_bit(1); // Sending EOF
|
repeat (3) send_bit(1); // Sending Interframe
|
repeat (3) send_bit(1); // Sending Interframe
|
|
|
// test_synchronization;
|
// test_synchronization;
|
|
|
|
|
|
/*
|
if(`CAN_CLOCK_DIVIDER_MODE) // Extended mode
|
if(`CAN_CLOCK_DIVIDER_MODE) // Extended mode
|
begin
|
begin
|
// test_empty_fifo_ext; // test currently switched off
|
// test_empty_fifo_ext; // test currently switched off
|
test_full_fifo_ext; // test currently switched on
|
test_full_fifo_ext; // test currently switched on
|
// send_frame_ext; // test currently switched off
|
// send_frame_ext; // test currently switched off
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// test_empty_fifo; // test currently switched off
|
// test_empty_fifo; // test currently switched off
|
// test_full_fifo; // test currently switched off
|
// test_full_fifo; // test currently switched off
|
send_frame; // test currently switched off
|
send_frame; // test currently switched off
|
// bus_off_test; // test currently switched off
|
// bus_off_test; // test currently switched off
|
// manual_frame; // test currently switched off
|
// manual_frame; // test currently switched off
|
// forced_bus_off; // test currently switched on
|
// forced_bus_off; // test currently switched on
|
end
|
end
|
|
*/
|
|
self_reception_request;
|
|
|
$display("CAN Testbench finished !");
|
$display("CAN Testbench finished !");
|
$stop;
|
$stop;
|
end
|
end
|
|
|
|
|
task forced_bus_off; // Forcing bus-off by writinf to tx_err_cnt register
|
task forced_bus_off; // Forcing bus-off by writinf to tx_err_cnt register
|
begin
|
begin
|
|
|
// Switch-on reset mode
|
// Switch-on reset mode
|
write_register(8'd0, {7'h0, `CAN_MODE_RESET});
|
write_register(8'd0, {7'h0, `CAN_MODE_RESET});
|
|
|
// Set Clock Divider register
|
// Set Clock Divider register
|
write_register(8'd31, {1'b1, 7'h0}); // Setting the extended mode (not normal)
|
write_register(8'd31, {1'b1, 7'h0}); // Setting the extended mode (not normal)
|
|
|
// Write 255 to tx_err_cnt register - Forcing bus-off
|
// Write 255 to tx_err_cnt register - Forcing bus-off
|
write_register(8'd15, 255);
|
write_register(8'd15, 255);
|
|
|
// Switch-off reset mode
|
// Switch-off reset mode
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
|
|
// #1000000;
|
// #1000000;
|
#2500000;
|
#2500000;
|
|
|
|
|
// Switch-on reset mode
|
// Switch-on reset mode
|
write_register(8'd0, {7'h0, `CAN_MODE_RESET});
|
write_register(8'd0, {7'h0, `CAN_MODE_RESET});
|
|
|
// Write 245 to tx_err_cnt register
|
// Write 245 to tx_err_cnt register
|
write_register(8'd15, 245);
|
write_register(8'd15, 245);
|
|
|
// Switch-off reset mode
|
// Switch-off reset mode
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
|
|
#1000000;
|
#1000000;
|
|
|
|
|
end
|
end
|
endtask // forced_bus_off
|
endtask // forced_bus_off
|
|
|
|
|
task manual_frame; // Testbench sends a frame
|
task manual_frame; // Testbench sends a frame
|
begin
|
begin
|
|
|
write_register(8'd10, 8'he8); // Writing ID[10:3] = 0xe8
|
write_register(8'd10, 8'he8); // Writing ID[10:3] = 0xe8
|
write_register(8'd11, 8'hb7); // Writing ID[2:0] = 0x5, rtr = 1, length = 7
|
write_register(8'd11, 8'hb7); // Writing ID[2:0] = 0x5, rtr = 1, length = 7
|
write_register(8'd12, 8'h00); // data byte 1
|
write_register(8'd12, 8'h00); // data byte 1
|
write_register(8'd13, 8'h00); // data byte 2
|
write_register(8'd13, 8'h00); // data byte 2
|
write_register(8'd14, 8'h00); // data byte 3
|
write_register(8'd14, 8'h00); // data byte 3
|
write_register(8'd15, 8'h00); // data byte 4
|
write_register(8'd15, 8'h00); // data byte 4
|
write_register(8'd16, 8'h00); // data byte 5
|
write_register(8'd16, 8'h00); // data byte 5
|
write_register(8'd17, 8'h00); // data byte 6
|
write_register(8'd17, 8'h00); // data byte 6
|
write_register(8'd18, 8'h00); // data byte 7
|
write_register(8'd18, 8'h00); // data byte 7
|
write_register(8'd19, 8'h00); // data byte 8
|
write_register(8'd19, 8'h00); // data byte 8
|
|
|
fork
|
fork
|
begin
|
begin
|
tx_request;
|
tx_request_command;
|
end
|
end
|
|
|
begin
|
begin
|
#2000;
|
#2000;
|
|
|
repeat (16)
|
repeat (16)
|
begin
|
begin
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // RTR
|
send_bit(1); // RTR
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0
|
send_bit(0); // r0
|
send_bit(0); // DLC
|
send_bit(0); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC DELIM
|
send_bit(1); // CRC DELIM
|
send_bit(1); // ACK ack error
|
send_bit(1); // ACK ack error
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
end // repeat
|
end // repeat
|
|
|
// Node is error passive now.
|
// Node is error passive now.
|
repeat (20)
|
repeat (20)
|
|
|
begin
|
begin
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // RTR
|
send_bit(1); // RTR
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0
|
send_bit(0); // r0
|
send_bit(0); // DLC
|
send_bit(0); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC DELIM
|
send_bit(1); // CRC DELIM
|
send_bit(1); // ACK ack error
|
send_bit(1); // ACK ack error
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
end // repeat
|
end // repeat
|
|
|
// Node is bus-off now
|
// Node is bus-off now
|
|
|
#100000;
|
#100000;
|
|
|
// Switch-off reset mode
|
// Switch-off reset mode
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
|
|
repeat (128 * 11)
|
repeat (128 * 11)
|
begin
|
begin
|
send_bit(1);
|
send_bit(1);
|
end // repeat
|
end // repeat
|
|
|
end
|
end
|
|
|
|
|
join
|
join
|
|
|
|
|
|
|
fork
|
fork
|
begin
|
begin
|
tx_request;
|
tx_request_command;
|
end
|
end
|
|
|
begin
|
begin
|
#1100;
|
#1100;
|
|
|
send_bit(1); // To spend some time before transmitter is ready.
|
send_bit(1); // To spend some time before transmitter is ready.
|
|
|
repeat (1)
|
repeat (1)
|
begin
|
begin
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // RTR
|
send_bit(1); // RTR
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0
|
send_bit(0); // r0
|
send_bit(0); // DLC
|
send_bit(0); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC DELIM
|
send_bit(1); // CRC DELIM
|
send_bit(0); // ACK
|
send_bit(0); // ACK
|
send_bit(1); // ACK DELIM
|
send_bit(1); // ACK DELIM
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
end // repeat
|
end // repeat
|
end
|
end
|
|
|
join
|
join
|
|
|
|
|
|
|
|
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
|
|
#4000000;
|
#4000000;
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
task bus_off_test; // Testbench sends a frame
|
task bus_off_test; // Testbench sends a frame
|
begin
|
begin
|
|
|
write_register(8'd10, 8'he8); // Writing ID[10:3] = 0xe8
|
write_register(8'd10, 8'he8); // Writing ID[10:3] = 0xe8
|
write_register(8'd11, 8'hb7); // Writing ID[2:0] = 0x5, rtr = 1, length = 7
|
write_register(8'd11, 8'hb7); // Writing ID[2:0] = 0x5, rtr = 1, length = 7
|
write_register(8'd12, 8'h00); // data byte 1
|
write_register(8'd12, 8'h00); // data byte 1
|
write_register(8'd13, 8'h00); // data byte 2
|
write_register(8'd13, 8'h00); // data byte 2
|
write_register(8'd14, 8'h00); // data byte 3
|
write_register(8'd14, 8'h00); // data byte 3
|
write_register(8'd15, 8'h00); // data byte 4
|
write_register(8'd15, 8'h00); // data byte 4
|
write_register(8'd16, 8'h00); // data byte 5
|
write_register(8'd16, 8'h00); // data byte 5
|
write_register(8'd17, 8'h00); // data byte 6
|
write_register(8'd17, 8'h00); // data byte 6
|
write_register(8'd18, 8'h00); // data byte 7
|
write_register(8'd18, 8'h00); // data byte 7
|
write_register(8'd19, 8'h00); // data byte 8
|
write_register(8'd19, 8'h00); // data byte 8
|
|
|
fork
|
fork
|
begin
|
begin
|
tx_request;
|
tx_request_command;
|
end
|
end
|
|
|
begin
|
begin
|
#2000;
|
#2000;
|
|
|
repeat (16)
|
repeat (16)
|
begin
|
begin
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // RTR
|
send_bit(1); // RTR
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0
|
send_bit(0); // r0
|
send_bit(0); // DLC
|
send_bit(0); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC DELIM
|
send_bit(1); // CRC DELIM
|
send_bit(1); // ACK ack error
|
send_bit(1); // ACK ack error
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
end // repeat
|
end // repeat
|
|
|
// Node is error passive now.
|
// Node is error passive now.
|
|
|
|
// Read irq register (error interrupt should be cleared now.
|
|
read_register(8'd3);
|
|
|
repeat (20)
|
repeat (20)
|
|
|
begin
|
begin
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // RTR
|
send_bit(1); // RTR
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0
|
send_bit(0); // r0
|
send_bit(0); // DLC
|
send_bit(0); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC DELIM
|
send_bit(1); // CRC DELIM
|
send_bit(1); // ACK ack error
|
send_bit(1); // ACK ack error
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(0); // ERROR
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // ERROR DELIM
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
send_bit(1); // SUSPEND
|
end // repeat
|
end // repeat
|
|
|
// Node is bus-off now
|
// Node is bus-off now
|
|
|
|
|
|
// Read irq register (error interrupt should be cleared now.
|
|
read_register(8'd3);
|
|
|
|
|
|
|
#100000;
|
#100000;
|
|
|
// Switch-off reset mode
|
// Switch-off reset mode
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
|
|
repeat (128 * 11)
|
repeat (64 * 11)
|
|
begin
|
|
send_bit(1);
|
|
end // repeat
|
|
|
|
// Read irq register (error interrupt should be cleared now.
|
|
read_register(8'd3);
|
|
|
|
repeat (64 * 11)
|
begin
|
begin
|
send_bit(1);
|
send_bit(1);
|
end // repeat
|
end // repeat
|
|
|
|
|
|
|
|
// Read irq register (error interrupt should be cleared now.
|
|
read_register(8'd3);
|
|
|
end
|
end
|
|
|
|
|
|
|
join
|
join
|
|
|
|
|
|
|
fork
|
fork
|
begin
|
begin
|
tx_request;
|
tx_request_command;
|
end
|
end
|
|
|
begin
|
begin
|
#1100;
|
#1100;
|
|
|
send_bit(1); // To spend some time before transmitter is ready.
|
send_bit(1); // To spend some time before transmitter is ready.
|
|
|
repeat (1)
|
repeat (1)
|
begin
|
begin
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(0); // ID
|
send_bit(0); // ID
|
send_bit(1); // ID
|
send_bit(1); // ID
|
send_bit(1); // RTR
|
send_bit(1); // RTR
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0
|
send_bit(0); // r0
|
send_bit(0); // DLC
|
send_bit(0); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // DLC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(0); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC
|
send_bit(1); // CRC DELIM
|
send_bit(1); // CRC DELIM
|
send_bit(0); // ACK
|
send_bit(0); // ACK
|
send_bit(1); // ACK DELIM
|
send_bit(1); // ACK DELIM
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // EOF
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
send_bit(1); // INTER
|
end // repeat
|
end // repeat
|
end
|
end
|
|
|
join
|
join
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
|
|
#4000000;
|
#4000000;
|
|
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h1, 15'h30bb); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h1, 15'h30bb); // mode, rtr, id, length, crc
|
|
|
#1000000;
|
#1000000;
|
|
|
end
|
end
|
endtask // bus_off_test
|
endtask // bus_off_test
|
|
|
|
|
|
|
task send_frame; // CAN IP core sends frames
|
task send_frame; // CAN IP core sends frames
|
begin
|
begin
|
|
|
if(`CAN_CLOCK_DIVIDER_MODE) // Extended mode
|
if(extended_mode) // Extended mode
|
begin
|
begin
|
|
|
// Writing TX frame information + identifier + data
|
// Writing TX frame information + identifier + data
|
write_register(8'd16, 8'h12);
|
write_register(8'd16, 8'h12);
|
write_register(8'd17, 8'h34);
|
write_register(8'd17, 8'h34);
|
write_register(8'd18, 8'h56);
|
write_register(8'd18, 8'h56);
|
write_register(8'd19, 8'h78);
|
write_register(8'd19, 8'h78);
|
write_register(8'd20, 8'h9a);
|
write_register(8'd20, 8'h9a);
|
write_register(8'd21, 8'hbc);
|
write_register(8'd21, 8'hbc);
|
write_register(8'd22, 8'hde);
|
write_register(8'd22, 8'hde);
|
write_register(8'd23, 8'hf0);
|
write_register(8'd23, 8'hf0);
|
write_register(8'd24, 8'h0f);
|
write_register(8'd24, 8'h0f);
|
write_register(8'd25, 8'hed);
|
write_register(8'd25, 8'hed);
|
write_register(8'd26, 8'hcb);
|
write_register(8'd26, 8'hcb);
|
write_register(8'd27, 8'ha9);
|
write_register(8'd27, 8'ha9);
|
write_register(8'd28, 8'h87);
|
write_register(8'd28, 8'h87);
|
end
|
end
|
else
|
else
|
begin
|
begin
|
write_register(8'd10, 8'hea); // Writing ID[10:3] = 0xea
|
write_register(8'd10, 8'hea); // Writing ID[10:3] = 0xea
|
write_register(8'd11, 8'h28); // Writing ID[2:0] = 0x1, rtr = 0, length = 8
|
write_register(8'd11, 8'h28); // Writing ID[2:0] = 0x1, rtr = 0, length = 8
|
write_register(8'd12, 8'h56); // data byte 1
|
write_register(8'd12, 8'h56); // data byte 1
|
write_register(8'd13, 8'h78); // data byte 2
|
write_register(8'd13, 8'h78); // data byte 2
|
write_register(8'd14, 8'h9a); // data byte 3
|
write_register(8'd14, 8'h9a); // data byte 3
|
write_register(8'd15, 8'hbc); // data byte 4
|
write_register(8'd15, 8'hbc); // data byte 4
|
write_register(8'd16, 8'hde); // data byte 5
|
write_register(8'd16, 8'hde); // data byte 5
|
write_register(8'd17, 8'hf0); // data byte 6
|
write_register(8'd17, 8'hf0); // data byte 6
|
write_register(8'd18, 8'h0f); // data byte 7
|
write_register(8'd18, 8'h0f); // data byte 7
|
write_register(8'd19, 8'hed); // data byte 8
|
write_register(8'd19, 8'hed); // data byte 8
|
end
|
end
|
|
|
|
|
// Enable irqs (basic mode)
|
// Enable irqs (basic mode)
|
write_register(8'd0, 8'h1e);
|
write_register(8'd0, 8'h1e);
|
|
|
|
|
|
|
fork
|
fork
|
begin
|
begin
|
$display("\n\nStart receiving data from CAN bus");
|
$display("\n\nStart receiving data from CAN bus");
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h1, 15'h30bb); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h1, 15'h30bb); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h2, 15'h2da1); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h2, 15'h2da1); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000ee, 3'h1}, 4'h0, 15'h6cea); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000ee, 3'h1}, 4'h0, 15'h6cea); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000ee, 3'h1}, 4'h1, 15'h00c5); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000ee, 3'h1}, 4'h1, 15'h00c5); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000ee, 3'h1}, 4'h2, 15'h7b4a); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000ee, 3'h1}, 4'h2, 15'h7b4a); // mode, rtr, id, length, crc
|
|
|
end
|
end
|
|
|
begin
|
begin
|
tx_request;
|
tx_request_command;
|
end
|
end
|
|
|
begin
|
begin
|
// Transmitting acknowledge
|
// Transmitting acknowledge
|
wait (can_testbench.i_can_top.i_can_bsp.tx_state & can_testbench.i_can_top.i_can_bsp.rx_ack);
|
wait (can_testbench.i_can_top.i_can_bsp.tx_state & can_testbench.i_can_top.i_can_bsp.rx_ack);
|
#1 rx = 0;
|
#1 rx = 0;
|
wait (can_testbench.i_can_top.i_can_bsp.rx_ack_lim);
|
wait (can_testbench.i_can_top.i_can_bsp.rx_ack_lim);
|
#1 rx = 1;
|
#1 rx = 1;
|
end
|
end
|
|
|
|
|
join
|
join
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
|
|
#200000;
|
#200000;
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
|
|
// Read irq register
|
// Read irq register
|
read_register(8'd3);
|
read_register(8'd3);
|
#1000;
|
#1000;
|
|
|
end
|
end
|
endtask // send_frame
|
endtask // send_frame
|
|
|
|
|
|
|
|
task self_reception_request; // CAN IP core sends sets self reception mode and transmits a msg. This test runs in EXTENDED mode
|
|
begin
|
|
|
|
// Switch-on reset mode
|
|
write_register(8'd0, {7'h0, (`CAN_MODE_RESET)});
|
|
|
|
// Set Clock Divider register
|
|
extended_mode = 1'b1;
|
|
write_register(8'd31, {extended_mode, 7'h0}); // Setting the extended mode
|
|
|
|
// Set Acceptance Code and Acceptance Mask registers
|
|
write_register(8'd16, 8'ha6); // acceptance code 0
|
|
write_register(8'd17, 8'hb0); // acceptance code 1
|
|
write_register(8'd18, 8'h12); // acceptance code 2
|
|
write_register(8'd19, 8'h30); // acceptance code 3
|
|
write_register(8'd20, 8'h00); // acceptance mask 0
|
|
write_register(8'd21, 8'h00); // acceptance mask 1
|
|
write_register(8'd22, 8'h00); // acceptance mask 2
|
|
write_register(8'd23, 8'h00); // acceptance mask 3
|
|
|
|
// Setting the "self test mode"
|
|
write_register(8'd0, 8'h4);
|
|
|
|
// Switch-off reset mode
|
|
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
|
|
|
|
// After exiting the reset mode sending bus free
|
|
repeat (11) send_bit(1);
|
|
|
|
|
|
// Writing TX frame information + identifier + data
|
|
write_register(8'd16, 8'h45); // Frame format = 0, Remote transmision request = 1, DLC = 5
|
|
write_register(8'd17, 8'ha6); // ID[28:21] = a6
|
|
write_register(8'd18, 8'ha0); // ID[20:18] = 5
|
|
// write_register(8'd19, 8'h78); RTR does not send any data
|
|
// write_register(8'd20, 8'h9a);
|
|
// write_register(8'd21, 8'hbc);
|
|
// write_register(8'd22, 8'hde);
|
|
// write_register(8'd23, 8'hf0);
|
|
// write_register(8'd24, 8'h0f);
|
|
// write_register(8'd25, 8'hed);
|
|
// write_register(8'd26, 8'hcb);
|
|
// write_register(8'd27, 8'ha9);
|
|
// write_register(8'd28, 8'h87);
|
|
|
|
|
|
// Enabling IRQ's (extended mode)
|
|
write_register(8'd4, 8'hff);
|
|
|
|
// tx_request_command;
|
|
self_reception_request_command;
|
|
|
|
#400000;
|
|
|
|
read_receive_buffer;
|
|
release_rx_buffer_command;
|
|
release_rx_buffer_command;
|
|
read_receive_buffer;
|
|
release_rx_buffer_command;
|
|
read_receive_buffer;
|
|
release_rx_buffer_command;
|
|
read_receive_buffer;
|
|
release_rx_buffer_command;
|
|
read_receive_buffer;
|
|
|
|
|
|
read_receive_buffer;
|
|
|
|
// Read irq register
|
|
read_register(8'd3);
|
|
#1000;
|
|
|
|
end
|
|
endtask // self_reception_request
|
|
|
|
|
|
|
task test_empty_fifo;
|
task test_empty_fifo;
|
begin
|
begin
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h3, 15'h7bcb); // mode, rtr, id, length, crc
|
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h7, 15'h085c); // mode, rtr, id, length, crc
|
// Enable irqs (basic mode)
|
|
write_register(8'd0, 8'h1e);
|
|
|
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h3, 15'h56a9); // mode, rtr, id, length, crc
|
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h7, 15'h391d); // mode, rtr, id, length, crc
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h00000e8, 3'h1}, 4'h8, 15'h70e0); // mode, rtr, id, length, crc
|
|
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
task test_empty_fifo_ext;
|
task test_empty_fifo_ext;
|
begin
|
begin
|
receive_frame(1, 0, 29'h14d60246, 4'h3, 15'h5262); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h3, 15'h5262); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h7, 15'h1730); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h7, 15'h1730); // mode, rtr, id, length, crc
|
|
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
receive_frame(1, 0, 29'h14d60246, 4'h8, 15'h2f7a); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h8, 15'h2f7a); // mode, rtr, id, length, crc
|
|
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
task test_full_fifo;
|
task test_full_fifo;
|
begin
|
begin
|
|
|
// Enable irqs (basic mode)
|
// Enable irqs (basic mode)
|
write_register(8'd0, 8'h1e);
|
write_register(8'd0, 8'h1e);
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h0, 15'h4edd); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h0, 15'h4edd); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h1, 15'h1ccf); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h1, 15'h1ccf); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h2, 15'h73f4); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h2, 15'h73f4); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h3, 15'h7bcb); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h3, 15'h7bcb); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h4, 15'h37da); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h4, 15'h37da); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h5, 15'h7e15); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h5, 15'h7e15); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h6, 15'h39cf); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h6, 15'h39cf); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h7, 15'h085c); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h7, 15'h085c); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
$display("FIFO should be full now");
|
$display("FIFO should be full now");
|
|
|
// Following one is accepted with overrun
|
// Following one is accepted with overrun
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
fifo_info;
|
fifo_info;
|
|
|
// Space just enough for the following frame.
|
// Space just enough for the following frame.
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h0, 15'h4edd); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h0, 15'h4edd); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
|
|
// Following accepted with overrun
|
// Following accepted with overrun
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
read_overrun_info(0, 15);
|
read_overrun_info(0, 15);
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
receive_frame(0, 0, {26'h0000008, 3'h1}, 4'h8, 15'h57a0); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
read_overrun_info(0, 15);
|
read_overrun_info(0, 15);
|
$display("\n\n");
|
$display("\n\n");
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
clear_data_overrun;
|
clear_data_overrun_command;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
clear_data_overrun;
|
clear_data_overrun_command;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
// Read irq register
|
// Read irq register
|
read_register(8'd3);
|
read_register(8'd3);
|
|
|
// Read irq register
|
// Read irq register
|
read_register(8'd3);
|
read_register(8'd3);
|
#1000;
|
#1000;
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
task test_full_fifo_ext;
|
task test_full_fifo_ext;
|
begin
|
begin
|
release_rx_buffer;
|
release_rx_buffer_command;
|
$display("\n\n");
|
$display("\n\n");
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
receive_frame(1, 0, 29'h14d60246, 4'h0, 15'h6f54); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h0, 15'h6f54); // mode, rtr, id, length, crc
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h1, 15'h6d38); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h1, 15'h6d38); // mode, rtr, id, length, crc
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h2, 15'h053e); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h2, 15'h053e); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
read_receive_buffer;
|
read_receive_buffer;
|
receive_frame(1, 0, 29'h14d60246, 4'h3, 15'h5262); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h3, 15'h5262); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h4, 15'h4bba); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h4, 15'h4bba); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h5, 15'h4d7d); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h5, 15'h4d7d); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h6, 15'h6f40); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h6, 15'h6f40); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h7, 15'h1730); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h7, 15'h1730); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
read_overrun_info(0, 10);
|
read_overrun_info(0, 10);
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
release_rx_buffer;
|
release_rx_buffer_command;
|
fifo_info;
|
fifo_info;
|
receive_frame(1, 0, 29'h14d60246, 4'h8, 15'h2f7a); // mode, rtr, id, length, crc
|
receive_frame(1, 0, 29'h14d60246, 4'h8, 15'h2f7a); // mode, rtr, id, length, crc
|
fifo_info;
|
fifo_info;
|
read_overrun_info(0, 15);
|
read_overrun_info(0, 15);
|
$display("\n\n");
|
$display("\n\n");
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
release_rx_buffer;
|
release_rx_buffer_command;
|
read_receive_buffer;
|
read_receive_buffer;
|
fifo_info;
|
fifo_info;
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
task initialize_fifo;
|
task initialize_fifo;
|
integer i;
|
integer i;
|
begin
|
begin
|
for (i=0; i<32; i=i+1)
|
for (i=0; i<32; i=i+1)
|
begin
|
begin
|
can_testbench.i_can_top.i_can_bsp.i_can_fifo.length_info[i] = 0;
|
can_testbench.i_can_top.i_can_bsp.i_can_fifo.length_info[i] = 0;
|
can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[i] = 0;
|
can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[i] = 0;
|
end
|
end
|
|
|
for (i=0; i<64; i=i+1)
|
for (i=0; i<64; i=i+1)
|
begin
|
begin
|
can_testbench.i_can_top.i_can_bsp.i_can_fifo.fifo[i] = 0;
|
can_testbench.i_can_top.i_can_bsp.i_can_fifo.fifo[i] = 0;
|
end
|
end
|
|
|
$display("(%0t) Fifo initialized", $time);
|
$display("(%0t) Fifo initialized", $time);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task read_overrun_info;
|
task read_overrun_info;
|
input [4:0] start_addr;
|
input [4:0] start_addr;
|
input [4:0] end_addr;
|
input [4:0] end_addr;
|
integer i;
|
integer i;
|
begin
|
begin
|
for (i=start_addr; i<=end_addr; i=i+1)
|
for (i=start_addr; i<=end_addr; i=i+1)
|
begin
|
begin
|
$display("len[0x%0x]=0x%0x", i, can_testbench.i_can_top.i_can_bsp.i_can_fifo.length_info[i]);
|
$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]);
|
$display("overrun[0x%0x]=0x%0x\n", i, can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[i]);
|
end
|
end
|
end
|
end
|
endtask
|
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.
|
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
|
begin
|
$display("(%0t) Currently %0d bytes in fifo (%0d packets)", $time, can_testbench.i_can_top.i_can_bsp.i_can_fifo.fifo_cnt,
|
$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));
|
(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
|
end
|
endtask
|
endtask
|
|
|
|
|
task read_register;
|
task read_register;
|
input [7:0] reg_addr;
|
input [7:0] reg_addr;
|
|
|
begin
|
begin
|
wait (wb_free);
|
wait (wb_free);
|
wb_free = 0;
|
wb_free = 0;
|
@ (posedge wb_clk_i);
|
@ (posedge wb_clk_i);
|
#1;
|
#1;
|
wb_adr_i = reg_addr;
|
wb_adr_i = reg_addr;
|
wb_cyc_i = 1;
|
wb_cyc_i = 1;
|
wb_stb_i = 1;
|
wb_stb_i = 1;
|
wb_we_i = 0;
|
wb_we_i = 0;
|
wait (wb_ack_o);
|
wait (wb_ack_o);
|
$display("(%0t) Reading register [%0d] = 0x%0x", $time, wb_adr_i, wb_dat_o);
|
$display("(%0t) Reading register [%0d] = 0x%0x", $time, wb_adr_i, wb_dat_o);
|
@ (posedge wb_clk_i);
|
@ (posedge wb_clk_i);
|
#1;
|
#1;
|
wb_adr_i = 'hz;
|
wb_adr_i = 'hz;
|
wb_cyc_i = 0;
|
wb_cyc_i = 0;
|
wb_stb_i = 0;
|
wb_stb_i = 0;
|
wb_we_i = 'hz;
|
wb_we_i = 'hz;
|
wb_free = 1;
|
wb_free = 1;
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task write_register;
|
task write_register;
|
input [7:0] reg_addr;
|
input [7:0] reg_addr;
|
input [7:0] reg_data;
|
input [7:0] reg_data;
|
|
|
begin
|
begin
|
wait (wb_free);
|
wait (wb_free);
|
wb_free = 0;
|
wb_free = 0;
|
@ (posedge wb_clk_i);
|
@ (posedge wb_clk_i);
|
#1;
|
#1;
|
wb_adr_i = reg_addr;
|
wb_adr_i = reg_addr;
|
wb_dat_i = reg_data;
|
wb_dat_i = reg_data;
|
wb_cyc_i = 1;
|
wb_cyc_i = 1;
|
wb_stb_i = 1;
|
wb_stb_i = 1;
|
wb_we_i = 1;
|
wb_we_i = 1;
|
wait (wb_ack_o);
|
wait (wb_ack_o);
|
@ (posedge wb_clk_i);
|
@ (posedge wb_clk_i);
|
#1;
|
#1;
|
wb_adr_i = 'hz;
|
wb_adr_i = 'hz;
|
wb_dat_i = 'hz;
|
wb_dat_i = 'hz;
|
wb_cyc_i = 0;
|
wb_cyc_i = 0;
|
wb_stb_i = 0;
|
wb_stb_i = 0;
|
wb_we_i = 'hz;
|
wb_we_i = 'hz;
|
wb_free = 1;
|
wb_free = 1;
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task read_receive_buffer;
|
task read_receive_buffer;
|
integer i;
|
integer i;
|
begin
|
begin
|
if(`CAN_CLOCK_DIVIDER_MODE) // Extended mode
|
if(extended_mode) // Extended mode
|
begin
|
begin
|
for (i=8'd16; i<=8'd28; i=i+1)
|
for (i=8'd16; i<=8'd28; i=i+1)
|
read_register(i);
|
read_register(i);
|
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[can_testbench.i_can_top.i_can_bsp.i_can_fifo.rd_info_pointer])
|
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[can_testbench.i_can_top.i_can_bsp.i_can_fifo.rd_info_pointer])
|
$display("\nWARNING: This packet was received with overrun.");
|
$display("\nWARNING: This packet was received with overrun.");
|
end
|
end
|
else
|
else
|
begin
|
begin
|
for (i=8'd20; i<=8'd29; i=i+1)
|
for (i=8'd20; i<=8'd29; i=i+1)
|
read_register(i);
|
read_register(i);
|
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[can_testbench.i_can_top.i_can_bsp.i_can_fifo.rd_info_pointer])
|
if (can_testbench.i_can_top.i_can_bsp.i_can_fifo.overrun_info[can_testbench.i_can_top.i_can_bsp.i_can_fifo.rd_info_pointer])
|
$display("\nWARNING: This packet was received with overrun.");
|
$display("\nWARNING: This packet was received with overrun.");
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task release_rx_buffer;
|
task release_rx_buffer_command;
|
begin
|
begin
|
write_register(8'd1, 8'h4);
|
write_register(8'd1, 8'h4);
|
$display("(%0t) Rx buffer released.", $time);
|
$display("(%0t) Rx buffer released.", $time);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task tx_request;
|
task tx_request_command;
|
begin
|
begin
|
write_register(8'd1, 8'h1);
|
write_register(8'd1, 8'h1);
|
$display("(%0t) Tx requested.", $time);
|
$display("(%0t) Tx requested.", $time);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task tx_abort;
|
task tx_abort_command;
|
begin
|
begin
|
write_register(8'd1, 8'h2);
|
write_register(8'd1, 8'h2);
|
$display("(%0t) Tx abort requested.", $time);
|
$display("(%0t) Tx abort requested.", $time);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task clear_data_overrun;
|
task clear_data_overrun_command;
|
begin
|
begin
|
write_register(8'd1, 8'h8);
|
write_register(8'd1, 8'h8);
|
$display("(%0t) Data overrun cleared.", $time);
|
$display("(%0t) Data overrun cleared.", $time);
|
end
|
end
|
|
endtask
|
|
|
|
|
|
task self_reception_request_command;
|
|
begin
|
|
write_register(8'd1, 8'h10);
|
|
$display("(%0t) Self reception requested.", $time);
|
|
end
|
endtask
|
endtask
|
|
|
|
|
task test_synchronization;
|
task test_synchronization;
|
begin
|
begin
|
// Hard synchronization
|
// Hard synchronization
|
#1 rx=0;
|
#1 rx=0;
|
repeat (2*BRP) @ (posedge clk);
|
repeat (2*BRP) @ (posedge clk);
|
repeat (8*BRP) @ (posedge clk);
|
repeat (8*BRP) @ (posedge clk);
|
#1 rx=1;
|
#1 rx=1;
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
|
|
// Resynchronization on time
|
// Resynchronization on time
|
#1 rx=0;
|
#1 rx=0;
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
#1 rx=1;
|
#1 rx=1;
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
|
|
// Resynchronization late
|
// Resynchronization late
|
repeat (BRP) @ (posedge clk);
|
repeat (BRP) @ (posedge clk);
|
repeat (BRP) @ (posedge clk);
|
repeat (BRP) @ (posedge clk);
|
#1 rx=0;
|
#1 rx=0;
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
#1 rx=1;
|
#1 rx=1;
|
|
|
// Resynchronization early
|
// Resynchronization early
|
repeat (8*BRP) @ (posedge clk); // two frames too early
|
repeat (8*BRP) @ (posedge clk); // two frames too early
|
#1 rx=0;
|
#1 rx=0;
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
#1 rx=1;
|
#1 rx=1;
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task send_bit;
|
task send_bit;
|
input bit;
|
input bit;
|
integer cnt;
|
integer cnt;
|
begin
|
begin
|
#1 rx=bit;
|
#1 rx=bit;
|
repeat ((`CAN_TIMING1_TSEG1 + `CAN_TIMING1_TSEG2 + 3)*BRP) @ (posedge clk);
|
repeat ((`CAN_TIMING1_TSEG1 + `CAN_TIMING1_TSEG2 + 3)*BRP) @ (posedge clk);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task receive_frame; // CAN IP core receives frames
|
task receive_frame; // CAN IP core receives frames
|
input mode;
|
input mode;
|
input remote_trans_req;
|
input remote_trans_req;
|
input [28:0] id;
|
input [28:0] id;
|
input [3:0] length;
|
input [3:0] length;
|
input [14:0] crc;
|
input [14:0] crc;
|
|
|
reg [117:0] data;
|
reg [117:0] data;
|
reg previous_bit;
|
reg previous_bit;
|
reg stuff;
|
reg stuff;
|
reg tmp;
|
reg tmp;
|
reg arbitration_lost;
|
reg arbitration_lost;
|
integer pointer;
|
integer pointer;
|
integer cnt;
|
integer cnt;
|
integer total_bits;
|
integer total_bits;
|
integer stuff_cnt;
|
integer stuff_cnt;
|
|
|
begin
|
begin
|
|
|
stuff_cnt = 1;
|
stuff_cnt = 1;
|
stuff = 0;
|
stuff = 0;
|
|
|
if(mode) // Extended format
|
if(mode) // Extended format
|
data = {id[28:18], 1'b1, 1'b1, id[17:0], remote_trans_req, 2'h0, length};
|
data = {id[28:18], 1'b1, 1'b1, id[17:0], remote_trans_req, 2'h0, length};
|
else // Standard format
|
else // Standard format
|
data = {id[10:0], remote_trans_req, 1'b0, 1'b0, length};
|
data = {id[10:0], remote_trans_req, 1'b0, 1'b0, length};
|
|
|
if (~remote_trans_req)
|
if (~remote_trans_req)
|
begin
|
begin
|
if(length) // Send data if length is > 0
|
if(length) // Send data if length is > 0
|
begin
|
begin
|
for (cnt=1; cnt<=(2*length); cnt=cnt+1) // data (we are sending nibbles)
|
for (cnt=1; cnt<=(2*length); cnt=cnt+1) // data (we are sending nibbles)
|
data = {data[113:0], cnt[3:0]};
|
data = {data[113:0], cnt[3:0]};
|
end
|
end
|
end
|
end
|
|
|
// Adding CRC
|
// Adding CRC
|
data = {data[104:0], crc[14:0]};
|
data = {data[104:0], crc[14:0]};
|
|
|
|
|
// Calculating pointer that points to the bit that will be send
|
// Calculating pointer that points to the bit that will be send
|
if (remote_trans_req)
|
if (remote_trans_req)
|
begin
|
begin
|
if(mode) // Extended format
|
if(mode) // Extended format
|
pointer = 52;
|
pointer = 52;
|
else // Standard format
|
else // Standard format
|
pointer = 32;
|
pointer = 32;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if(mode) // Extended format
|
if(mode) // Extended format
|
pointer = 52 + 8 * length;
|
pointer = 52 + 8 * length;
|
else // Standard format
|
else // Standard format
|
pointer = 32 + 8 * length;
|
pointer = 32 + 8 * length;
|
end
|
end
|
|
|
// This is how many bits we need to shift
|
// This is how many bits we need to shift
|
total_bits = pointer;
|
total_bits = pointer;
|
|
|
// Waiting until previous msg is finished before sending another one
|
// 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.
|
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) &
|
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.rx_inter ) &
|
(~can_testbench.i_can_top.i_can_bsp.tx_state )
|
(~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.
|
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) &
|
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.rx_inter )
|
);
|
);
|
arbitration_lost = 0;
|
arbitration_lost = 0;
|
|
|
send_bit(0); // SOF
|
send_bit(0); // SOF
|
previous_bit = 0;
|
previous_bit = 0;
|
|
|
fork
|
fork
|
|
|
begin
|
begin
|
for (cnt=0; cnt<=total_bits; cnt=cnt+1)
|
for (cnt=0; cnt<=total_bits; cnt=cnt+1)
|
begin
|
begin
|
if (stuff_cnt == 5)
|
if (stuff_cnt == 5)
|
begin
|
begin
|
stuff_cnt = 1;
|
stuff_cnt = 1;
|
total_bits = total_bits + 1;
|
total_bits = total_bits + 1;
|
stuff = 1;
|
stuff = 1;
|
tmp = ~data[pointer+1];
|
tmp = ~data[pointer+1];
|
send_bit(~data[pointer+1]);
|
send_bit(~data[pointer+1]);
|
previous_bit = ~data[pointer+1];
|
previous_bit = ~data[pointer+1];
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (data[pointer] == previous_bit)
|
if (data[pointer] == previous_bit)
|
stuff_cnt <= stuff_cnt + 1;
|
stuff_cnt <= stuff_cnt + 1;
|
else
|
else
|
stuff_cnt <= 1;
|
stuff_cnt <= 1;
|
|
|
stuff = 0;
|
stuff = 0;
|
tmp = data[pointer];
|
tmp = data[pointer];
|
send_bit(data[pointer]);
|
send_bit(data[pointer]);
|
previous_bit = data[pointer];
|
previous_bit = data[pointer];
|
pointer = pointer - 1;
|
pointer = pointer - 1;
|
end
|
end
|
if (arbitration_lost)
|
if (arbitration_lost)
|
cnt=total_bits+1; // Exit the for loop
|
cnt=total_bits+1; // Exit the for loop
|
end
|
end
|
|
|
// Nothing send after the data (just recessive bit)
|
// 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
|
repeat (13) send_bit(1); // CRC delimiter + ack + ack delimiter + EOF + intermission= 1 + 1 + 1 + 7 + 3
|
end
|
end
|
|
|
begin
|
begin
|
while (mode ? (cnt<32) : (cnt<12))
|
while (mode ? (cnt<32) : (cnt<12))
|
begin
|
begin
|
#1 wait (can_testbench.i_can_top.sample_point);
|
#1 wait (can_testbench.i_can_top.sample_point);
|
if (mode)
|
if (mode)
|
begin
|
begin
|
if (cnt<32 & tmp & (~rx_and_tx))
|
if (cnt<32 & tmp & (~rx_and_tx))
|
begin
|
begin
|
arbitration_lost = 1;
|
arbitration_lost = 1;
|
rx = 1; // Only recessive is send from now on.
|
rx = 1; // Only recessive is send from now on.
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (cnt<12 & tmp & (~rx_and_tx))
|
if (cnt<12 & tmp & (~rx_and_tx))
|
begin
|
begin
|
arbitration_lost = 1;
|
arbitration_lost = 1;
|
rx = 1; // Only recessive is send from now on.
|
rx = 1; // Only recessive is send from now on.
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
join
|
join
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
// State machine monitor (btl)
|
// State machine monitor (btl)
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
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 |
|
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)
|
can_testbench.i_can_top.i_can_btl.go_seg1 & can_testbench.i_can_top.i_can_btl.go_seg2)
|
begin
|
begin
|
$display("(%0t) ERROR multiple go_sync, go_seg1 or go_seg2 occurance\n\n", $time);
|
$display("(%0t) ERROR multiple go_sync, go_seg1 or go_seg2 occurance\n\n", $time);
|
#1000;
|
#1000;
|
$stop;
|
$stop;
|
end
|
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 |
|
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)
|
can_testbench.i_can_top.i_can_btl.seg1 & can_testbench.i_can_top.i_can_btl.seg2)
|
begin
|
begin
|
$display("(%0t) ERROR multiple sync, seg1 or seg2 occurance\n\n", $time);
|
$display("(%0t) ERROR multiple sync, seg1 or seg2 occurance\n\n", $time);
|
#1000;
|
#1000;
|
$stop;
|
$stop;
|
end
|
end
|
end
|
end
|
|
|
/* stuff_error monitor (bsp)
|
/* stuff_error monitor (bsp)
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if(can_testbench.i_can_top.i_can_bsp.stuff_error)
|
if(can_testbench.i_can_top.i_can_bsp.stuff_error)
|
begin
|
begin
|
$display("\n\n(%0t) Stuff error occured in can_bsp.v file\n\n", $time);
|
$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
|
$stop; After everything is finished add another condition (something like & (~idle)) and enable stop
|
end
|
end
|
end
|
end
|
*/
|
*/
|
|
|
//
|
//
|
// CRC monitor (used until proper CRC generation is used in testbench
|
// CRC monitor (used until proper CRC generation is used in testbench
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if (can_testbench.i_can_top.i_can_bsp.rx_ack &
|
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.sample_point &
|
can_testbench.i_can_top.i_can_bsp.crc_err
|
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);
|
$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
|
end
|
|
|
|
|
|
|
|
|
|
|
/*
|
/*
|
// overrun monitor
|
// overrun monitor
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
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)
|
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);
|
$display("(%0t)overrun", $time);
|
end
|
end
|
*/
|
*/
|
|
|
|
|
// form error monitor
|
// form error monitor
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if (can_testbench.i_can_top.i_can_bsp.form_err)
|
if (can_testbench.i_can_top.i_can_bsp.form_err)
|
$display("*E (%0t) ERROR: form_error", $time);
|
$display("*E (%0t) ERROR: form_error", $time);
|
end
|
end
|
|
|
|
|
|
|
// acknowledge error monitor
|
// acknowledge error monitor
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if (can_testbench.i_can_top.i_can_bsp.ack_err)
|
if (can_testbench.i_can_top.i_can_bsp.ack_err)
|
$display("*E (%0t) ERROR: acknowledge_error", $time);
|
$display("*E (%0t) ERROR: acknowledge_error", $time);
|
end
|
end
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|