Line 43... |
Line 43... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.7 2002/12/28 04:13:53 mohor
|
|
// 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.
|
Line 88... |
Line 91... |
reg cs, rw;
|
reg cs, rw;
|
reg [7:0] addr;
|
reg [7:0] addr;
|
reg rx;
|
reg rx;
|
integer start_tb;
|
integer start_tb;
|
|
|
/* Instantiate can_top module */
|
// Instantiate can_top module
|
can_top i_can_top
|
can_top i_can_top
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.rst(rst),
|
.rst(rst),
|
.data_in(data_in),
|
.data_in(data_in),
|
Line 128... |
Line 131... |
// 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'h6, {`CAN_TIMING0_SJW, `CAN_TIMING0_BRP});
|
write_register(8'h6, {`CAN_TIMING0_SJW, `CAN_TIMING0_BRP});
|
|
|
/* Set bus timing register 1 */
|
// Set bus timing register 1
|
write_register(8'h7, {`CAN_TIMING1_SAM, `CAN_TIMING1_TSEG2, `CAN_TIMING1_TSEG1});
|
write_register(8'h7, {`CAN_TIMING1_SAM, `CAN_TIMING1_TSEG2, `CAN_TIMING1_TSEG1});
|
|
|
|
// Set Clock Divider register
|
|
write_register(8'h31, {`CAN_CLOCK_DIVIDER_MODE, 7'h0}); // Setting the normal mode (not extended)
|
|
|
|
// 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
|
|
write_register(8'h16, 8'ha6); // acceptance code 0
|
|
write_register(8'h17, 8'hb0); // acceptance code 1
|
|
write_register(8'h18, 8'h12); // acceptance code 2
|
|
write_register(8'h19, 8'h34); // acceptance code 3
|
|
write_register(8'h20, 8'h0); // acceptance mask 0
|
|
write_register(8'h21, 8'h0); // acceptance mask 1
|
|
write_register(8'h22, 8'h0); // acceptance mask 2
|
|
write_register(8'h23, 8'h0); // acceptance mask 3
|
|
end
|
|
else
|
|
begin
|
|
// Set Acceptance Code and Acceptance Mask registers
|
|
write_register(8'h4, 8'ha6); // acceptance code
|
|
write_register(8'h5, 8'h00); // acceptance mask
|
|
end
|
|
|
#10;
|
#10;
|
repeat (1000) @ (posedge clk);
|
repeat (1000) @ (posedge clk);
|
|
|
/* Switch-off reset mode */
|
// Switch-off reset mode
|
write_register(8'h0, {7'h0, ~(`CAN_MODE_RESET)});
|
write_register(8'h0, {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.
|
|
repeat (7) send_bit(1); // Sending EOF
|
|
|
// test_synchronization;
|
// test_synchronization;
|
|
|
repeat (7) send_bit(1); // Sending EOF
|
|
|
|
|
|
send_frame(1, 29'h00075678, 1); // mode, id, length
|
if(`CAN_CLOCK_DIVIDER_MODE) // Extended mode
|
|
begin
|
|
send_frame(0, 1, {26'h00000a6, 3'h5}, 2, 15'h2a11); // mode, rtr, id, length, crc
|
|
// send_frame(0, 1, 29'h12567635, 2, 15'h75b4); // mode, rtr, id, length, crc
|
|
end
|
|
else
|
|
begin
|
|
send_frame(0, 1, {26'h00000a6, 3'h5}, 2, 15'h2a11); // mode, rtr, id, length, crc
|
|
end
|
|
|
|
|
repeat (50000) @ (posedge clk);
|
repeat (50000) @ (posedge clk);
|
$display("CAN Testbench finished.");
|
$display("CAN Testbench finished.");
|
$stop;
|
$stop;
|
Line 185... |
Line 219... |
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);
|
// #1 idle = 0;
|
|
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;
|
// idle = 0;
|
|
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;
|
// idle = 0;
|
|
|
|
// 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;
|
// idle = 0;
|
|
repeat (10*BRP) @ (posedge clk);
|
repeat (10*BRP) @ (posedge clk);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
Line 222... |
Line 252... |
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);
|
// idle=0;
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task send_frame;
|
task send_frame;
|
input mode;
|
input mode;
|
|
input remote_trans_req;
|
input [28:0] id;
|
input [28:0] id;
|
input [3:0] length;
|
input [3:0] length;
|
|
input [14:0] crc;
|
integer cnt;
|
integer cnt;
|
|
|
reg [28:0] data;
|
reg [28:0] data;
|
reg [3:0] len;
|
reg [3:0] len;
|
begin
|
begin
|
Line 258... |
Line 289... |
begin
|
begin
|
send_bit(data[28]);
|
send_bit(data[28]);
|
data=data<<1;
|
data=data<<1;
|
end
|
end
|
|
|
send_bit(0); // RTR
|
send_bit(remote_trans_req);
|
send_bit(0); // r1 (reserved 1)
|
send_bit(0); // r1 (reserved 1)
|
send_bit(0); // r0 (reserved 0)
|
send_bit(0); // r0 (reserved 0)
|
|
|
for (cnt=0; cnt<4; cnt=cnt+1) // DLC (length)
|
for (cnt=0; cnt<4; cnt=cnt+1) // DLC (length)
|
begin
|
begin
|
Line 275... |
Line 306... |
for (cnt=0; cnt<11; cnt=cnt+1) // 11 bit ID
|
for (cnt=0; cnt<11; cnt=cnt+1) // 11 bit ID
|
begin
|
begin
|
send_bit(data[10]);
|
send_bit(data[10]);
|
data=data<<1;
|
data=data<<1;
|
end
|
end
|
send_bit(0); // RTR
|
send_bit(remote_trans_req);
|
send_bit(0); // IDE
|
send_bit(0); // IDE
|
send_bit(0); // r0 (reserved 0)
|
send_bit(0); // r0 (reserved 0)
|
|
|
for (cnt=0; cnt<4; cnt=cnt+1) // DLC (length)
|
for (cnt=0; cnt<4; cnt=cnt+1) // DLC (length)
|
begin
|
begin
|
Line 287... |
Line 318... |
len=len<<1;
|
len=len<<1;
|
end
|
end
|
end // End header
|
end // End header
|
|
|
|
|
for (cnt=0; cnt<(8*length); cnt=cnt+4) // data
|
if(length) // Send data if length is > 0
|
|
begin
|
|
for (cnt=1; cnt<=(2*length); cnt=cnt+1) // data (we are sending nibbles)
|
begin
|
begin
|
send_bit(cnt[3]);
|
send_bit(cnt[3]);
|
send_bit(cnt[2]);
|
send_bit(cnt[2]);
|
send_bit(cnt[1]);
|
send_bit(cnt[1]);
|
send_bit(cnt[0]);
|
send_bit(cnt[0]);
|
end
|
end
|
|
end
|
|
|
|
// Send CRC
|
|
data[14:0] = crc[14:0];
|
|
for (cnt=0; cnt<15; cnt=cnt+1) // 15 bit CRC
|
|
begin
|
|
send_bit(data[14]);
|
|
data=data<<1;
|
|
end
|
|
|
|
// Send CRC delimiter
|
|
send_bit(1);
|
|
|
|
// Send ACK slot
|
|
send_bit(1);
|
|
|
|
// Send Ack delimiter
|
|
send_bit(1);
|
|
|
|
|
// Nothing send after the data (just recessive bit)
|
// Nothing send after the data (just recessive bit)
|
send_bit(1);
|
send_bit(1);
|
|
|
Line 305... |
Line 356... |
|
|
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
|