URL
https://opencores.org/ocsvn/can/can/trunk
Subversion Repositories can
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 9 to Rev 10
- ↔ Reverse comparison
Rev 9 → Rev 10
/trunk/bench/verilog/can_testbench_defines.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2002/12/27 00:12:48 mohor |
// Header changed, testbench improved to send a frame (crc still missing). |
// |
// Revision 1.1 2002/12/26 16:00:29 mohor |
// Testbench define file added. Clock divider register added. |
// |
52,6 → 55,9
// |
// |
|
// Mode register |
`define CAN_MODE_RESET 1'h1 // Reset mode |
|
// Bit Timing 0 register value |
`define CAN_TIMING0_BRP 6'h1 // Baud rate prescaler (2*(value+1)) |
`define CAN_TIMING0_SJW 2'h2 // SJW (value+1) |
/trunk/bench/verilog/can_testbench.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.6 2002/12/27 00:12:48 mohor |
// Header changed, testbench improved to send a frame (crc still missing). |
// |
// Revision 1.5 2002/12/26 16:00:29 mohor |
// Testbench define file added. Clock divider register added. |
// |
85,7 → 88,6
reg cs, rw; |
reg [7:0] addr; |
reg rx; |
reg idle; |
integer start_tb; |
|
/* Instantiate can_top module */ |
98,8 → 100,7
.cs(cs), |
.rw(rw), |
.addr(addr), |
.rx(rx), |
.idle(idle) |
.rx(rx) |
); |
|
|
119,7 → 120,6
addr = 'hz; |
rx = 1; |
rst = 1; |
idle = 1; |
#200 rst = 0; |
#200 start_tb = 1; |
end |
139,9 → 139,18
#10; |
repeat (1000) @ (posedge clk); |
|
/* Switch-off reset mode */ |
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 |
// This difference is resynchronized later. |
|
// test_synchronization; |
repeat (2) @ (posedge clk); // So we are not synchronized to anything |
send_frame(1, 29'h12345678, 1); // mode, id, length |
|
repeat (7) send_bit(1); // Sending EOF |
|
|
send_frame(1, 29'h00075678, 1); // mode, id, length |
|
|
repeat (50000) @ (posedge clk); |
176,10 → 185,9
task test_synchronization; |
begin |
// Hard synchronization |
repeat (2) @ (posedge clk); // So we are not synchronized to anything |
#1 rx=0; |
repeat (2*BRP) @ (posedge clk); |
#1 idle = 0; |
// #1 idle = 0; |
repeat (8*BRP) @ (posedge clk); |
#1 rx=1; |
repeat (10*BRP) @ (posedge clk); |
188,7 → 196,7
#1 rx=0; |
repeat (10*BRP) @ (posedge clk); |
#1 rx=1; |
idle = 0; |
// idle = 0; |
repeat (10*BRP) @ (posedge clk); |
|
// Resynchronization late |
197,7 → 205,7
#1 rx=0; |
repeat (10*BRP) @ (posedge clk); |
#1 rx=1; |
idle = 0; |
// idle = 0; |
|
// Resynchronization early |
repeat (8*BRP) @ (posedge clk); // two frames too early |
204,7 → 212,7
#1 rx=0; |
repeat (10*BRP) @ (posedge clk); |
#1 rx=1; |
idle = 0; |
// idle = 0; |
repeat (10*BRP) @ (posedge clk); |
end |
endtask |
216,7 → 224,7
begin |
#1 rx=bit; |
repeat ((`CAN_TIMING1_TSEG1 + `CAN_TIMING1_TSEG2 + 3)*BRP) @ (posedge clk); |
idle=0; |
// idle=0; |
end |
endtask |
|
304,11 → 312,31
begin |
if(can_testbench.i_can_top.i_can_btl.go_sync & can_testbench.i_can_top.i_can_btl.go_seg1 | can_testbench.i_can_top.i_can_btl.go_sync & can_testbench.i_can_top.i_can_btl.go_seg2 | |
can_testbench.i_can_top.i_can_btl.go_seg1 & can_testbench.i_can_top.i_can_btl.go_seg2) |
$display("(%0t) ERROR multiple go_sync, go_seg1 or go_seg2 occurance", $time); |
begin |
$display("(%0t) ERROR multiple go_sync, go_seg1 or go_seg2 occurance\n\n", $time); |
#1000; |
$stop; |
end |
|
if(can_testbench.i_can_top.i_can_btl.sync & can_testbench.i_can_top.i_can_btl.seg1 | can_testbench.i_can_top.i_can_btl.sync & can_testbench.i_can_top.i_can_btl.seg2 | |
can_testbench.i_can_top.i_can_btl.seg1 & can_testbench.i_can_top.i_can_btl.seg2) |
$display("(%0t) ERROR multiple sync, seg1 or seg2 occurance", $time); |
begin |
$display("(%0t) ERROR multiple sync, seg1 or seg2 occurance\n\n", $time); |
#1000; |
$stop; |
end |
end |
|
/* stuff_error monitor (bsp) |
always @ (posedge clk) |
begin |
if(can_testbench.i_can_top.i_can_bsp.stuff_error) |
begin |
$display("\n\n(%0t) Stuff error occured in can_bsp.v file\n\n", $time); |
$stop; After everything is finished add another condition (something like & (~idle)) and enable stop |
end |
end |
*/ |
|
|
endmodule |
/trunk/rtl/verilog/can_btl.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.5 2002/12/27 00:12:52 mohor |
// Header changed, testbench improved to send a frame (crc still missing). |
// |
// Revision 1.4 2002/12/26 01:33:05 mohor |
// Tripple sampling supported. |
// |
72,7 → 75,7
rx, |
|
/* Mode register */ |
reset_mode, // Not used !!! |
reset_mode, |
|
/* Bus Timing 0 register */ |
baud_r_presc, |
84,12 → 87,15
triple_sampling, |
|
/* Output signals from this module */ |
take_sample, |
clk_en, |
sample_point, |
sampled_bit, |
sampled_bit_q, |
|
/* States */ |
idle |
/* Output from can_bsp module */ |
rx_idle |
|
|
|
|
); |
100,7 → 106,7
input rst; |
input rx; |
|
/* Mode register */ |
/* Mode register */ |
input reset_mode; |
|
/* Bus Timing 0 register */ |
112,11 → 118,15
input [2:0] time_segment2; |
input triple_sampling; |
|
/* Output from can_bsp module */ |
input rx_idle; |
|
/* Output signals from this module */ |
output take_sample; // NOT USED, YET |
output clk_en; |
output sample_point; |
output sampled_bit; |
output sampled_bit_q; |
|
input idle; |
|
|
reg [8:0] clk_cnt; |
123,6 → 133,7
reg clk_en; |
reg sync_blocked; |
reg sampled_bit; |
reg sampled_bit_q; |
reg [7:0] quant_cnt; |
reg [3:0] delay; |
reg sync; |
129,7 → 140,7
reg seg1; |
reg seg2; |
reg resync_latched; |
reg sample_pulse; |
reg sample_point; |
reg [1:0] sample; |
|
wire go_sync; |
143,8 → 154,8
|
|
assign preset_cnt = (baud_r_presc + 1'b1)<<1; // (BRP+1)*2 |
assign hard_sync = idle & (~rx) & sampled_bit & (~sync_blocked); // Hard synchronization |
assign resync = (~idle) & (~rx) & sampled_bit & (~sync_blocked); // Re-synchronization |
assign hard_sync = rx_idle & (~rx) & sampled_bit & (~sync_blocked); // Hard synchronization |
assign resync = (~rx_idle) & (~rx) & sampled_bit & (~sync_blocked); // Re-synchronization |
|
|
/* Generating general enable signal that defines baud rate. */ |
151,31 → 162,33
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
begin |
clk_cnt <= 0; |
clk_en <= 1'b0; |
end |
clk_cnt <= 0; |
else if (clk_cnt == (preset_cnt-1) | reset_mode) |
clk_cnt <=#Tp 0; |
else |
clk_cnt <=#Tp clk_cnt + 1; |
end |
|
|
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
clk_en <= 1'b0; |
else if (clk_cnt == (preset_cnt-1)) |
begin |
clk_cnt <=#Tp 0; |
clk_en <=#Tp 1'b1; |
end |
clk_en <=#Tp 1'b1; |
else |
begin |
clk_cnt <=#Tp clk_cnt + 1; |
clk_en <=#Tp 1'b0; |
end |
clk_en <=#Tp 1'b0; |
end |
|
|
|
/* Changing states */ |
//assign go_sync = clk_en & (seg2 & (~resync) & ((quant_cnt == time_segment2))); |
assign go_sync = clk_en & (seg2 & ((quant_cnt == time_segment2))); |
assign go_seg1 = clk_en & (sync | hard_sync | (resync & seg2 & sync_window) | (resync_latched & sync_window)); |
assign go_seg2 = clk_en & (seg1 & (quant_cnt == (time_segment1 + delay))); |
assign go_sync = clk_en & (seg2 & (~hard_sync) & (~resync) & ((quant_cnt == time_segment2))); |
assign go_seg1 = clk_en & (sync | hard_sync | (resync & seg2 & sync_window) | (resync_latched & sync_window)); |
assign go_seg2 = clk_en & (seg1 & (~hard_sync) & (quant_cnt == (time_segment1 + delay))); |
|
|
|
/* When early edge is detected outside of the SJW field, synchronization request is latched and performed when |
SJW is reached */ |
always @ (posedge clk or posedge rst) |
194,7 → 207,7
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
sync <= 1; |
sync <= 0; |
else if (go_sync) |
sync <=#Tp 1'b1; |
else if (go_seg1) |
206,7 → 219,7
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
seg1 <= 0; |
seg1 <= 1; |
else if (go_seg1) |
seg1 <=#Tp 1'b1; |
else if (go_seg2) |
270,13 → 283,15
if (rst) |
begin |
sampled_bit <= 1; |
sample_pulse <= 0; |
sampled_bit_q <= 1; |
sample_point <= 0; |
end |
else if (clk_en) |
begin |
if (seg1 & (quant_cnt == (time_segment1 + delay))) |
begin |
sample_pulse <=#Tp 1; |
sample_point <=#Tp 1; |
sampled_bit_q <=#Tp sampled_bit; |
if (triple_sampling) |
sampled_bit <=#Tp (sample[0] & sample[1]) | ( sample[0] & rx) | (sample[1] & rx); |
else |
284,7 → 299,7
end |
end |
else |
sample_pulse <=#Tp 0; // Sample pulse is for development purposes only. REMOVE ME. |
sample_point <=#Tp 0; |
end |
|
|
/trunk/rtl/verilog/can_top.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/12/27 00:12:52 mohor |
// Header changed, testbench improved to send a frame (crc still missing). |
// |
// Revision 1.2 2002/12/26 16:00:34 mohor |
// Testbench define file added. Clock divider register added. |
// |
66,8 → 69,7
data_in, |
data_out, |
cs, rw, addr, |
rx, |
idle /* REMOVE and use correct "idle state" signal instead */ |
rx |
); |
|
parameter Tp = 1; |
79,7 → 81,6
input cs, rw; |
input [7:0] addr; |
input rx; |
input idle; /* REMOVE and use correct "idle state" signal instead */ |
|
|
/* Mode register */ |
143,12 → 144,17
|
|
/* Output signals from can_btl module */ |
wire take_sample; |
wire clk_en; |
wire sample_point; |
wire sampled_bit; |
wire sampled_bit_q; |
|
/* output from can_bsp module */ |
wire rx_idle; |
|
|
|
|
/* Connecting can_btl module */ |
can_btl i_can_btl |
( |
169,11 → 175,13
.triple_sampling(triple_sampling), |
|
/* Output signals from this module */ |
.take_sample(take_sample), |
.clk_en(clk_en), |
.sample_point(sample_point), |
.sampled_bit(sampled_bit), |
.sampled_bit_q(sampled_bit_q), |
|
/* States */ |
.idle(idle) |
/* output from can_bsp module */ |
.rx_idle(rx_idle) |
|
|
|
184,8 → 192,20
can_bsp i_can_bsp |
( |
.clk(clk), |
.rst(rst) |
.rst(rst), |
|
/* From btl module */ |
.sample_point(sample_point), |
.sampled_bit(sampled_bit), |
.sampled_bit_q(sampled_bit_q), |
|
/* Mode register */ |
.reset_mode(reset_mode), |
|
/* output from can_bsp module */ |
.rx_idle(rx_idle) |
|
|
); |
|
|
/trunk/rtl/verilog/can_bsp.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2002/12/27 00:12:52 mohor |
// Header changed, testbench improved to send a frame (crc still missing). |
// |
// Revision 1.1.1.1 2002/12/20 16:39:21 mohor |
// Initial |
// |
59,14 → 62,335
module can_bsp |
( |
clk, |
rst |
rst, |
|
sample_point, |
sampled_bit, |
sampled_bit_q, |
reset_mode, |
|
rx_idle |
|
|
); |
|
parameter Tp = 1; |
|
input clk; |
input rst; |
input clk; |
input rst; |
input sample_point; |
input sampled_bit; |
input sampled_bit_q; |
input reset_mode; |
|
output rx_idle; |
|
reg reset_mode_q; |
reg [5:0] bit_cnt; |
|
reg [3:0] data_len; |
reg [28:0] id; |
reg [2:0] bit_stuff_cnt; |
reg stuff_error; |
|
wire bit_de_stuff; |
|
|
/* Rx state machine */ |
wire go_rx_idle; |
wire go_rx_id1; |
wire go_rx_rtr1; |
wire go_rx_ide; |
wire go_rx_id2; |
wire go_rx_rtr2; |
wire go_rx_r1; |
wire go_rx_r0; |
wire go_rx_dlc; |
wire go_rx_data; |
wire go_rx_crc; |
wire go_rx_ack; |
wire go_rx_eof; |
|
reg rx_idle; |
reg rx_id1; |
reg rx_rtr1; |
reg rx_ide; |
reg rx_id2; |
reg rx_rtr2; |
reg rx_r1; |
reg rx_r0; |
reg rx_dlc; |
reg rx_data; |
reg rx_crc; |
reg rx_ack; |
reg rx_eof; |
|
reg [2:0] eof_cnt; |
|
|
assign go_rx_idle = sample_point & rx_eof & (eof_cnt == 6); |
assign go_rx_id1 = sample_point & rx_idle & (~sampled_bit); |
assign go_rx_rtr1 = sample_point & rx_id1 & (bit_cnt == 10); |
assign go_rx_ide = sample_point & rx_rtr1; |
assign go_rx_id2 = sample_point & rx_ide & sampled_bit; |
assign go_rx_rtr2 = sample_point & rx_id2 & (bit_cnt == 17); |
assign go_rx_r1 = sample_point & rx_rtr2; |
assign go_rx_r0 = sample_point & (rx_ide & (~sampled_bit) | rx_r1); |
assign go_rx_dlc = sample_point & rx_r0; |
assign go_rx_data = sample_point & rx_dlc & (bit_cnt == 3) & (sampled_bit | (|data_len[2:0])); |
assign go_rx_crc = sample_point & (rx_dlc & (bit_cnt == 3) & (~sampled_bit) & (~(|data_len[2:0])) |
| rx_data & (bit_cnt == ((data_len<<3) - 1'b1))); |
assign go_rx_ack = sample_point & rx_crc & (bit_cnt == 15); |
assign go_rx_eof = sample_point & rx_ack & (bit_cnt == 1) | (~reset_mode) & reset_mode_q; |
|
// Rx idle state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_idle <= 1'b1; |
else if (reset_mode | go_rx_id1) |
rx_idle <=#Tp 1'b0; |
else if (go_rx_idle) |
rx_idle <=#Tp 1'b1; |
end |
|
|
// Rx id1 state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_id1 <= 1'b0; |
else if (reset_mode | go_rx_rtr1) |
rx_id1 <=#Tp 1'b0; |
else if (go_rx_id1) |
rx_id1 <=#Tp 1'b1; |
end |
|
|
// Rx rtr1 state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_rtr1 <= 1'b0; |
else if (reset_mode | go_rx_ide) |
rx_rtr1 <=#Tp 1'b0; |
else if (go_rx_rtr1) |
rx_rtr1 <=#Tp 1'b1; |
end |
|
|
// Rx ide state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_ide <= 1'b0; |
else if (reset_mode | go_rx_r0 | go_rx_id2) |
rx_ide <=#Tp 1'b0; |
else if (go_rx_ide) |
rx_ide <=#Tp 1'b1; |
end |
|
|
// Rx id2 state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_id2 <= 1'b0; |
else if (reset_mode | go_rx_rtr2) |
rx_id2 <=#Tp 1'b0; |
else if (go_rx_id2) |
rx_id2 <=#Tp 1'b1; |
end |
|
|
// Rx rtr2 state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_rtr2 <= 1'b0; |
else if (reset_mode | go_rx_r1) |
rx_rtr2 <=#Tp 1'b0; |
else if (go_rx_rtr2) |
rx_rtr2 <=#Tp 1'b1; |
end |
|
|
// Rx r0 state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_r1 <= 1'b0; |
else if (reset_mode | go_rx_r0) |
rx_r1 <=#Tp 1'b0; |
else if (go_rx_r1) |
rx_r1 <=#Tp 1'b1; |
end |
|
|
// Rx r0 state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_r0 <= 1'b0; |
else if (reset_mode | go_rx_dlc) |
rx_r0 <=#Tp 1'b0; |
else if (go_rx_r0) |
rx_r0 <=#Tp 1'b1; |
end |
|
|
// Rx dlc state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_dlc <= 1'b0; |
else if (reset_mode | go_rx_data | go_rx_crc) |
rx_dlc <=#Tp 1'b0; |
else if (go_rx_dlc) |
rx_dlc <=#Tp 1'b1; |
end |
|
|
// Rx data state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_data <= 1'b0; |
else if (reset_mode | go_rx_crc) |
rx_data <=#Tp 1'b0; |
else if (go_rx_data) |
rx_data <=#Tp 1'b1; |
end |
|
|
// Rx crc state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_crc <= 1'b0; |
else if (reset_mode | go_rx_ack) |
rx_crc <=#Tp 1'b0; |
else if (go_rx_crc) |
rx_crc <=#Tp 1'b1; |
end |
|
|
// Rx ack state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_ack <= 1'b0; |
else if (reset_mode | go_rx_eof) |
rx_ack <=#Tp 1'b0; |
else if (go_rx_ack) |
rx_ack <=#Tp 1'b1; |
end |
|
|
// Rx eof state |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
rx_eof <= 1'b0; |
else if (go_rx_idle) |
rx_eof <=#Tp 1'b0; |
else if (go_rx_eof) |
rx_eof <=#Tp 1'b1; |
end |
|
|
|
|
|
|
|
|
// ID register |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
id <= 0; |
else if (sample_point & rx_id1 & (~bit_de_stuff)) |
id <=#Tp {id[27:0], sampled_bit}; |
end |
|
// Data length |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
data_len <= 0; |
else if (sample_point & rx_dlc & (~bit_de_stuff)) |
data_len <=#Tp {data_len[2:0], sampled_bit}; |
end |
|
|
// bit_cnt |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
bit_cnt <= 0; |
else if (go_rx_id1 | go_rx_id2 | go_rx_dlc | go_rx_data | go_rx_crc | go_rx_ack | go_rx_eof) |
bit_cnt <=#Tp 0; |
else if (sample_point) |
bit_cnt <=#Tp bit_cnt + 1'b1; |
end |
|
|
// eof_cnt |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
eof_cnt <= 0; |
else if (sample_point) |
begin |
if (rx_eof & sampled_bit) |
eof_cnt <=#Tp eof_cnt + 1'b1; |
else |
eof_cnt <=#Tp 0; |
end |
end |
|
|
|
|
|
// bit_stuff_cnt |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
bit_stuff_cnt <= 1; |
else if (sample_point & (rx_id1 | rx_id2 | rx_dlc | rx_data | rx_crc)) // Is this OK? Check again |
begin |
if (bit_stuff_cnt == 5) |
bit_stuff_cnt <=#Tp 1; |
else if (sampled_bit == sampled_bit_q) |
bit_stuff_cnt <=#Tp bit_stuff_cnt + 1'b1; |
else |
bit_stuff_cnt <=#Tp 1; |
end |
end |
|
|
assign bit_de_stuff = bit_stuff_cnt == 5; |
|
|
// stuff_error |
always @ (posedge clk or posedge rst) |
begin |
if (rst) |
stuff_error <= 0; |
else if (sample_point & (rx_id1) & bit_de_stuff & (sampled_bit == sampled_bit_q)) // Add other stages (data, control, etc.) !!! |
stuff_error <=#Tp 1'b1; |
// else if (reset condition) // Add reset condition |
// stuff_error <=#Tp 0; |
end |
|
|
// Generating delayed reset_mode signal |
always @ (posedge clk) |
begin |
reset_mode_q <=#Tp reset_mode; |
end |
|
|
endmodule |