?? can_testbench.v
字號:
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "can_defines.v"
`include "can_testbench_defines.v"
module can_testbench();
parameter Tp = 1;
parameter BRP = 2*(`CAN_TIMING0_BRP + 1);
`ifdef CAN_WISHBONE_IF
reg wb_clk_i;
reg wb_rst_i;
reg [7:0] wb_dat_i;
wire [7:0] wb_dat_o;
reg wb_cyc_i;
reg wb_stb_i;
reg wb_we_i;
reg [7:0] wb_adr_i;
wire wb_ack_o;
reg wb_free;
`else
reg rst_i;
reg ale_i;
reg rd_i;
reg wr_i;
wire [7:0] port_0;
wire [7:0] port_0_i;
reg [7:0] port_0_o;
reg port_0_en;
reg port_free;
`endif
reg cs_can;
reg clk;
reg rx;
wire tx;
wire irq;
wire clkout;
wire rx_and_tx;
integer start_tb;
reg [7:0] tmp_data;
reg delayed_tx;
reg tx_bypassed;
reg extended_mode;
// Instantiate can_top module
can_top i_can_top
(
`ifdef CAN_WISHBONE_IF
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o),
.wb_cyc_i(wb_cyc_i),
.wb_stb_i(wb_stb_i),
.wb_we_i(wb_we_i),
.wb_adr_i(wb_adr_i),
.wb_ack_o(wb_ack_o),
`else
.rst_i(rst_i),
.ale_i(ale_i),
.rd_i(rd_i),
.wr_i(wr_i),
.port_0_io(port_0),
`endif
.cs_can_i(cs_can),
.clk_i(clk),
.rx_i(rx_and_tx),
.tx_o(tx),
.irq_on(irq),
.clkout_o(clkout)
);
`ifdef CAN_WISHBONE_IF
// Generate wishbone clock signal 10 MHz
initial
begin
wb_clk_i=0;
forever #50 wb_clk_i = ~wb_clk_i;
end
`endif
`ifdef CAN_WISHBONE_IF
`else
assign port_0_i = port_0;
assign port_0 = port_0_en? port_0_o : 8'hz;
`endif
// Generate clock signal 24 MHz
initial
begin
clk=0;
forever #21 clk = ~clk;
end
initial
begin
start_tb = 0;
cs_can = 0;
rx = 1;
extended_mode = 0;
tx_bypassed = 0;
`ifdef CAN_WISHBONE_IF
wb_dat_i = 'hz;
wb_cyc_i = 0;
wb_stb_i = 0;
wb_we_i = 'hz;
wb_adr_i = 'hz;
wb_free = 1;
wb_rst_i = 1;
#200 wb_rst_i = 0;
#200 start_tb = 1;
`else
rst_i = 1'b0;
ale_i = 1'b0;
rd_i = 1'b0;
wr_i = 1'b0;
port_0_o = 8'h0;
port_0_en = 0;
port_free = 1;
rst_i = 1;
#200 rst_i = 0;
#200 start_tb = 1;
`endif
end
// Generating delayed tx signal (CAN transciever delay)
always
begin
wait (tx);
repeat (4*BRP) @ (posedge clk); // 4 time quants delay
#1 delayed_tx = tx;
wait (~tx);
repeat (4*BRP) @ (posedge clk); // 4 time quants delay
#1 delayed_tx = tx;
end
//assign rx_and_tx = rx & delayed_tx; FIX ME !!!
assign rx_and_tx = rx & (delayed_tx | tx_bypassed); // When this signal is on, tx is not looped back to the rx.
// Main testbench
initial
begin
wait(start_tb);
// Set bus timing register 0
write_register(8'd6, {`CAN_TIMING0_SJW, `CAN_TIMING0_BRP});
// Set bus timing register 1
write_register(8'd7, {`CAN_TIMING1_SAM, `CAN_TIMING1_TSEG2, `CAN_TIMING1_TSEG1});
// Set Clock Divider register
extended_mode = 1'b0;
write_register(8'd31, {extended_mode, 3'h0, 1'b0, 3'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
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'h0); // acceptance mask 0
write_register(8'd21, 8'h0); // acceptance mask 1
write_register(8'd22, 8'h00); // acceptance mask 2
write_register(8'd23, 8'h00); // acceptance mask 3
*/
// Set Acceptance Code and Acceptance Mask registers
write_register(8'd4, 8'he8); // acceptance code
write_register(8'd5, 8'h0f); // acceptance mask
#10;
repeat (1000) @ (posedge clk);
// Switch-off reset mode
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
// This difference is resynchronized later.
// After exiting the reset mode sending bus free
repeat (11) send_bit(1);
// test_synchronization; // test currently switched off
// test_empty_fifo_ext; // test currently switched off
// test_full_fifo_ext; // test currently switched off
// send_frame_ext; // test currently switched off
// test_empty_fifo; // test currently switched off
test_full_fifo; // test currently switched on
// send_frame; // test currently switched off
// bus_off_test; // test currently switched off
// forced_bus_off; // test currently switched off
// send_frame_basic; // test currently switched off
// send_frame_extended; // test currently switched off
// self_reception_request; // test currently switched off
// manual_frame_basic; // test currently switched off
// manual_frame_ext; // test currently switched off
$display("CAN Testbench finished !");
$stop;
end
task forced_bus_off; // Forcing bus-off by writinf to tx_err_cnt register
begin
// Switch-on reset mode
write_register(8'd0, {7'h0, `CAN_MODE_RESET});
// Set Clock Divider register
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_register(8'd15, 255);
// Switch-off reset mode
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
// #1000000;
#2500000;
// Switch-on reset mode
write_register(8'd0, {7'h0, `CAN_MODE_RESET});
// Write 245 to tx_err_cnt register
write_register(8'd15, 245);
// Switch-off reset mode
write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});
#1000000;
end
endtask // forced_bus_off
task manual_frame_basic; // Testbench sends a basic format frame
begin
// Switch-on reset mode
write_register(8'd0, {7'h0, (`CAN_MODE_RESET)});
// Set Acceptance Code and Acceptance Mask registers
write_register(8'd4, 8'h28); // acceptance code
write_register(8'd5, 8'hff); // acceptance mask
repeat (100) @ (posedge clk);
// 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);
write_register(8'd10, 8'h55); // Writing ID[10:3] = 0x55
write_register(8'd11, 8'h57); // Writing ID[2:0] = 0x2, rtr = 1, length = 7
write_register(8'd12, 8'h00); // data byte 1
write_register(8'd13, 8'h00); // data byte 2
write_register(8'd14, 8'h00); // data byte 3
write_register(8'd15, 8'h00); // data byte 4
write_register(8'd16, 8'h00); // data byte 5
write_register(8'd17, 8'h00); // data byte 6
write_register(8'd18, 8'h00); // data byte 7
write_register(8'd19, 8'h00); // data byte 8
tx_bypassed = 1; // When this signal is on, tx is not looped back to the rx.
fork
begin
// tx_request_command;
self_reception_request_command;
end
begin
#2200;
repeat (1)
begin
send_bit(0); // SOF
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // RTR
send_bit(0); // IDE
send_bit(0); // r0
send_bit(0); // 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 stuff
send_bit(0); // CRC 6
send_bit(0); // CRC
send_bit(0); // CRC
send_bit(0); // CRC
send_bit(1); // CRC stuff
send_bit(0); // CRC 0
send_bit(0); // CRC
send_bit(1); // CRC
send_bit(0); // CRC
send_bit(1); // CRC 5
send_bit(1); // CRC
send_bit(0); // CRC
send_bit(1); // CRC
send_bit(1); // CRC b
send_bit(1); // CRC DELIM
send_bit(0); // ACK
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); // INTER
send_bit(1); // INTER
send_bit(1); // INTER
end // repeat
end
join
read_receive_buffer;
release_rx_buffer_command;
read_receive_buffer;
release_rx_buffer_command;
read_receive_buffer;
#4000000;
end
endtask // manual_frame_basic
task manual_frame_ext; // Testbench sends an extended format frame
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'h00); // acceptance code 1
write_register(8'd18, 8'h5a); // acceptance code 2
write_register(8'd19, 8'hac); // 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
repeat (100) @ (posedge clk);
// 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);
// Extended frame format
// Writing TX frame information + identifier + data
write_register(8'd16, 8'hc5); // Frame format = 1, Remote transmision request = 1, DLC = 5
write_register(8'd17, 8'ha6); // ID[28:21] = a6
write_register(8'd18, 8'h00); // ID[20:13] = 00
write_register(8'd19, 8'h5a); // ID[12:5] = 5a
write_register(8'd20, 8'ha8); // ID[4:0] = 15
// write_register(8'd21, 8'h78); RTR does not send any data
// write_register(8'd22, 8'h9a);
// write_register(8'd23, 8'hbc);
// write_register(8'd24, 8'hde);
// write_register(8'd25, 8'hf0);
// write_register(8'd26, 8'h0f);
// write_register(8'd27, 8'hed);
// write_register(8'd28, 8'hcb);
// Enabling IRQ's (extended mode)
write_register(8'd4, 8'hff);
// tx_bypassed = 1; // When this signal is on, tx is not looped back to the rx.
fork
begin
tx_request_command;
// self_reception_request_command;
end
begin
#2400;
repeat (1)
begin
send_bit(0); // SOF
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID a
send_bit(0); // ID
send_bit(1); // ID
send_bit(1); // ID
send_bit(0); // ID 6
send_bit(0); // ID
send_bit(0); // ID
send_bit(0); // ID
send_bit(1); // RTR
send_bit(1); // IDE
send_bit(0); // ID 0
send_bit(0); // ID
send_bit(0); // ID
send_bit(0); // ID
send_bit(0); // ID 0
send_bit(1); // ID stuff
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID 6
send_bit(1); // ID
send_bit(0); // ID
send_bit(1); // ID
send_bit(0); // ID a
send_bit(1); // ID 1
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -