URL
https://opencores.org/ocsvn/can/can/trunk
Subversion Repositories can
[/] [can/] [tags/] [rel_7/] [rtl/] [verilog/] [can_bsp.v] - Rev 26
Go to most recent revision | Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// can_bsp.v //// //// //// //// //// //// This file is part of the CAN Protocol Controller //// //// http://www.opencores.org/projects/can/ //// //// //// //// //// //// Author(s): //// //// Igor Mohor //// //// igorm@opencores.org //// //// //// //// //// //// All additional information is available in the README.txt //// //// file. //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2002, 2003 Authors //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// // // CVS Revision History // // $Log: not supported by cvs2svn $ // Revision 1.16 2003/02/04 14:34:52 mohor // *** empty log message *** // // Revision 1.15 2003/01/31 01:13:37 mohor // backup. // // Revision 1.14 2003/01/16 13:36:19 mohor // 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. // (CAN specification ver 2.0, part B, page 57). // // Revision 1.13 2003/01/15 21:59:45 mohor // Data is stored to fifo at the end of ack stage. // // Revision 1.12 2003/01/15 21:05:11 mohor // CRC checking fixed (when bitstuff occurs at the end of a CRC sequence). // // Revision 1.11 2003/01/15 14:40:23 mohor // RX state machine fixed to receive "remote request" frames correctly. No data bytes are written to fifo when such frames are received. // // Revision 1.10 2003/01/15 13:16:47 mohor // When a frame with "remote request" is received, no data is stored to fifo, just the frame information (identifier, ...). Data length that is stored is the received data length and not the actual data length that is stored to fifo. // // Revision 1.9 2003/01/14 12:19:35 mohor // rx_fifo is now working. // // Revision 1.8 2003/01/10 17:51:33 mohor // Temporary version (backup). // // Revision 1.7 2003/01/09 21:54:45 mohor // rx fifo added. Not 100 % verified, yet. // // Revision 1.6 2003/01/09 14:46:58 mohor // Temporary files (backup). // // Revision 1.5 2003/01/08 13:30:31 mohor // Temp version. // // Revision 1.4 2003/01/08 02:10:53 mohor // Acceptance filter added. // // Revision 1.3 2002/12/28 04:13:23 mohor // Backup version. // // 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 // // // // synopsys translate_off `include "timescale.v" // synopsys translate_on `include "can_defines.v" module can_bsp ( clk, rst, sample_point, sampled_bit, sampled_bit_q, tx_point, hard_sync, addr, data_out, /* Mode register */ reset_mode, acceptance_filter_mode, /* Command register */ release_buffer, tx_request, /* Clock Divider register */ extended_mode, rx_idle, transmitting, /* This section is for BASIC and EXTENDED mode */ /* Acceptance code register */ acceptance_code_0, /* Acceptance mask register */ acceptance_mask_0, /* End: This section is for BASIC and EXTENDED mode */ /* This section is for EXTENDED mode */ /* Acceptance code register */ acceptance_code_1, acceptance_code_2, acceptance_code_3, /* Acceptance mask register */ acceptance_mask_1, acceptance_mask_2, acceptance_mask_3, /* End: This section is for EXTENDED mode */ /* Tx data registers. Holding identifier (basic mode), tx frame information (extended mode) and data */ tx_data_0, tx_data_1, tx_data_2, tx_data_3, tx_data_4, tx_data_5, tx_data_6, tx_data_7, tx_data_8, tx_data_9, tx_data_10, tx_data_11, tx_data_12, /* End: Tx data registers */ /* Tx signal */ tx ); parameter Tp = 1; input clk; input rst; input sample_point; input sampled_bit; input sampled_bit_q; input tx_point; input hard_sync; input [7:0] addr; output [7:0] data_out; input reset_mode; input acceptance_filter_mode; input extended_mode; /* Command register */ input release_buffer; input tx_request; output rx_idle; output transmitting; /* This section is for BASIC and EXTENDED mode */ /* Acceptance code register */ input [7:0] acceptance_code_0; /* Acceptance mask register */ input [7:0] acceptance_mask_0; /* End: This section is for BASIC and EXTENDED mode */ /* This section is for EXTENDED mode */ /* Acceptance code register */ input [7:0] acceptance_code_1; input [7:0] acceptance_code_2; input [7:0] acceptance_code_3; /* Acceptance mask register */ input [7:0] acceptance_mask_1; input [7:0] acceptance_mask_2; input [7:0] acceptance_mask_3; /* End: This section is for EXTENDED mode */ /* Tx data registers. Holding identifier (basic mode), tx frame information (extended mode) and data */ input [7:0] tx_data_0; input [7:0] tx_data_1; input [7:0] tx_data_2; input [7:0] tx_data_3; input [7:0] tx_data_4; input [7:0] tx_data_5; input [7:0] tx_data_6; input [7:0] tx_data_7; input [7:0] tx_data_8; input [7:0] tx_data_9; input [7:0] tx_data_10; input [7:0] tx_data_11; input [7:0] tx_data_12; /* End: Tx data registers */ /* Tx signal */ output tx; 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 [2:0] bit_stuff_cnt_tx; reg stuff_error; reg tx_point_q; wire bit_de_stuff; wire bit_de_stuff_tx; /* 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_crc_lim; wire go_rx_ack; wire go_rx_ack_lim; wire go_rx_eof; wire go_error_frame; wire go_overload_frame; wire go_rx_inter; wire go_crc_enable; wire rst_crc_enable; wire bit_de_stuff_set; wire bit_de_stuff_reset; wire go_early_tx; wire go_tx; 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_crc_lim; reg rx_ack; reg rx_ack_lim; reg rx_eof; reg rx_inter; reg rtr1; reg ide; reg rtr2; reg [14:0] crc_in; reg [7:0] tmp_data; reg [7:0] tmp_fifo [0:7]; reg write_data_to_tmp_fifo; reg [2:0] byte_cnt; reg bit_stuff_cnt_en; reg crc_enable; reg [2:0] eof_cnt; wire [14:0] calculated_crc; wire [15:0] r_calculated_crc; wire remote_rq; wire [3:0] limited_data_len; wire form_error; wire set_form_error; reg transmitting; reg error_frame; reg enable_error_cnt2; reg [2:0] error_cnt1; reg [2:0] error_cnt2; reg tx; reg crc_error; reg priority_lost; reg tx_q; wire error_frame_ended; wire bit_error; wire acknowledge_error; reg need_to_tx; // When the CAN core has something to transmit and a dominant bit is sampled at the third bit // of intermission, it starts reading the identifier (and transmitting its own). wire overload_needed = 0; // When receiver is busy, it needs to send overload frame. Only 2 overload frames are allowed to // be send in a row. This is not implemented because host can not send an overload request. FIX ME !!!! wire id_ok; // If received ID matches ID set in registers wire no_byte0; // There is no byte 0 (RTR bit set to 1 or DLC field equal to 0). Signal used for acceptance filter. wire no_byte1; // There is no byte 1 (RTR bit set to 1 or DLC field equal to 1). Signal used for acceptance filter. reg [3:0] data_cnt; // Counting the data bytes that are written to FIFO reg [2:0] header_cnt; // Counting header length reg wr_fifo; // Write data and header to 64-byte fifo reg [7:0] data_for_fifo;// Multiplexed data that is stored to 64-byte fifo reg [5:0] tx_pointer; reg tx_bit; reg tx_state; reg finish_msg; wire [2:0] header_len; wire storing_header; wire [3:0] limited_data_len_minus1; wire reset_wr_fifo; wire no_error; assign go_rx_idle = sample_point & sampled_bit & rx_inter & (bit_cnt == 2); // Look the following line for TX assign go_rx_id1 = sample_point & (~sampled_bit) & (rx_idle | rx_inter & (bit_cnt == 2)); assign go_rx_rtr1 = (~bit_de_stuff) & sample_point & rx_id1 & (bit_cnt == 10); assign go_rx_ide = (~bit_de_stuff) & sample_point & rx_rtr1; assign go_rx_id2 = (~bit_de_stuff) & sample_point & rx_ide & sampled_bit; assign go_rx_rtr2 = (~bit_de_stuff) & sample_point & rx_id2 & (bit_cnt == 17); assign go_rx_r1 = (~bit_de_stuff) & sample_point & rx_rtr2; assign go_rx_r0 = (~bit_de_stuff) & sample_point & (rx_ide & (~sampled_bit) | rx_r1); assign go_rx_dlc = (~bit_de_stuff) & sample_point & rx_r0; assign go_rx_data = (~bit_de_stuff) & sample_point & rx_dlc & (bit_cnt == 3) & (sampled_bit | (|data_len[2:0])) & (~remote_rq); assign go_rx_crc = (~bit_de_stuff) & sample_point & (rx_dlc & (bit_cnt == 3) & ((~sampled_bit) & (~(|data_len[2:0])) | remote_rq) | rx_data & (bit_cnt == ((limited_data_len<<3) - 1'b1))); assign go_rx_crc_lim = (~bit_de_stuff) & sample_point & rx_crc & (bit_cnt == 14); assign go_rx_ack = sample_point & rx_crc_lim; assign go_rx_ack_lim = sample_point & rx_ack; assign go_rx_eof = sample_point & rx_ack_lim | (~reset_mode) & reset_mode_q; assign go_rx_inter = ((sample_point & rx_eof & (eof_cnt == 6)) | error_frame_ended) & (~overload_needed); assign go_error_frame = form_error | stuff_error | bit_error | acknowledge_error | (crc_error & go_rx_eof); assign error_frame_ended = (error_cnt2 == 7) & tx_point; assign go_overload_frame = ((sample_point & rx_eof & (eof_cnt == 6)) | error_frame_ended) & overload_needed | sample_point & (~sampled_bit) & rx_inter & ((bit_cnt == 0) | (bit_cnt == 1)) | sample_point & (~sampled_bit) & (error_cnt2 == 7) ; assign go_crc_enable = hard_sync | go_tx; assign rst_crc_enable = go_rx_crc; assign bit_de_stuff_set = go_rx_id1; assign bit_de_stuff_reset = go_rx_crc_lim | reset_mode | go_error_frame; assign remote_rq = ((~ide) & rtr1) | (ide & rtr2); assign limited_data_len = (data_len < 8)? data_len : 4'h8; assign acknowledge_error = rx_ack & sample_point & sampled_bit & tx_state; assign bit_error = tx_state & sample_point & tx & (~sampled_bit) & (~rx_ack) & (~rx_id1) & (~rx_rtr1) & (~rx_ide) & (~rx_id2) & (~rx_rtr2); // Rx idle state always @ (posedge clk or posedge rst) begin if (rst) rx_idle <= 1'b0; else if (reset_mode | go_rx_id1 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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 | error_frame) 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_crc_lim | error_frame) rx_crc <=#Tp 1'b0; else if (go_rx_crc) rx_crc <=#Tp 1'b1; end // Rx crc delimiter state always @ (posedge clk or posedge rst) begin if (rst) rx_crc_lim <= 1'b0; else if (reset_mode | go_rx_ack | error_frame) rx_crc_lim <=#Tp 1'b0; else if (go_rx_crc_lim) rx_crc_lim <=#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_ack_lim | error_frame) rx_ack <=#Tp 1'b0; else if (go_rx_ack) rx_ack <=#Tp 1'b1; end // Rx ack delimiter state always @ (posedge clk or posedge rst) begin if (rst) rx_ack_lim <= 1'b0; else if (reset_mode | go_rx_eof | error_frame) rx_ack_lim <=#Tp 1'b0; else if (go_rx_ack_lim) rx_ack_lim <=#Tp 1'b1; end // Rx eof state always @ (posedge clk or posedge rst) begin if (rst) rx_eof <= 1'b0; else if (go_rx_inter | error_frame) rx_eof <=#Tp 1'b0; else if (go_rx_eof) rx_eof <=#Tp 1'b1; end // Interframe space always @ (posedge clk or posedge rst) begin if (rst) rx_inter <= 1'b0; else if (go_rx_idle | go_rx_id1 | go_overload_frame | go_error_frame) rx_inter <=#Tp 1'b0; else if (go_rx_inter) rx_inter <=#Tp 1'b1; end // ID register always @ (posedge clk or posedge rst) begin if (rst) id <= 0; else if (sample_point & (rx_id1 | rx_id2) & (~bit_de_stuff)) id <=#Tp {id[27:0], sampled_bit}; end // rtr1 bit always @ (posedge clk or posedge rst) begin if (rst) rtr1 <= 0; else if (sample_point & rx_rtr1 & (~bit_de_stuff)) rtr1 <=#Tp sampled_bit; end // rtr2 bit always @ (posedge clk or posedge rst) begin if (rst) rtr2 <= 0; else if (sample_point & rx_rtr2 & (~bit_de_stuff)) rtr2 <=#Tp sampled_bit; end // ide bit always @ (posedge clk or posedge rst) begin if (rst) ide <= 0; else if (sample_point & rx_ide & (~bit_de_stuff)) ide <=#Tp 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 // Data always @ (posedge clk or posedge rst) begin if (rst) tmp_data <= 0; else if (sample_point & rx_data & (~bit_de_stuff)) tmp_data <=#Tp {tmp_data[6:0], sampled_bit}; end always @ (posedge clk or posedge rst) begin if (rst) write_data_to_tmp_fifo <= 0; else if (sample_point & rx_data & (~bit_de_stuff) & (&bit_cnt[2:0])) write_data_to_tmp_fifo <=#Tp 1'b1; else write_data_to_tmp_fifo <=#Tp 0; end always @ (posedge clk or posedge rst) begin if (rst) byte_cnt <= 0; else if (write_data_to_tmp_fifo) byte_cnt <=#Tp byte_cnt + 1; else if (sample_point & go_rx_crc_lim) byte_cnt <=#Tp 0; end always @ (posedge clk) begin if (write_data_to_tmp_fifo) tmp_fifo[byte_cnt] <=#Tp tmp_data; end // CRC always @ (posedge clk or posedge rst) begin if (rst) crc_in <= 0; else if (sample_point & rx_crc & (~bit_de_stuff)) crc_in <=#Tp {crc_in[13: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 | go_rx_inter | go_error_frame | go_overload_frame) bit_cnt <=#Tp 0; else if (sample_point & (~bit_de_stuff)) 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 // Enabling bit de-stuffing always @ (posedge clk or posedge rst) begin if (rst) bit_stuff_cnt_en <= 1'b0; else if (bit_de_stuff_set) bit_stuff_cnt_en <=#Tp 1'b1; else if (bit_de_stuff_reset) bit_stuff_cnt_en <=#Tp 1'b0; end // bit_stuff_cnt always @ (posedge clk or posedge rst) begin if (rst) bit_stuff_cnt <= 1; else if (bit_de_stuff_reset) bit_stuff_cnt <=#Tp 1; else if (sample_point & bit_stuff_cnt_en) 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 // bit_stuff_cnt_tx always @ (posedge clk or posedge rst) begin if (rst) bit_stuff_cnt_tx <= 1; else if (bit_de_stuff_reset) bit_stuff_cnt_tx <=#Tp 1; else if (tx_point_q & bit_stuff_cnt_en) begin if (bit_stuff_cnt_tx == 5) bit_stuff_cnt_tx <=#Tp 1; else if (tx == tx_q) bit_stuff_cnt_tx <=#Tp bit_stuff_cnt_tx + 1'b1; else bit_stuff_cnt_tx <=#Tp 1; end end assign bit_de_stuff = bit_stuff_cnt == 5; assign bit_de_stuff_tx = bit_stuff_cnt_tx == 5; // stuff_error always @ (posedge clk or posedge rst) begin if (rst) stuff_error <= 0; else if (reset_mode | go_rx_idle | error_frame) // Stuff error might reset itself stuff_error <=#Tp 0; else if (sample_point & bit_stuff_cnt_en & bit_de_stuff & (sampled_bit == sampled_bit_q)) stuff_error <=#Tp 1'b1; end // Generating delayed reset_mode signal always @ (posedge clk) begin reset_mode_q <=#Tp reset_mode; end always @ (posedge clk or posedge rst) begin if (rst) crc_enable <= 1'b0; else if (go_crc_enable) crc_enable <=#Tp 1'b1; else if (reset_mode | rst_crc_enable) crc_enable <=#Tp 1'b0; end // CRC error generation always @ (posedge clk or posedge rst) begin if (rst) crc_error <= 0; else if (go_rx_ack) crc_error <=#Tp crc_in != calculated_crc; else if (reset_mode | go_rx_idle | error_frame) crc_error <=#Tp 0; end // Conditions for form error assign form_error = sample_point & ( (~bit_de_stuff) & rx_ide & sampled_bit & (~rtr1) | rx_crc_lim & (~sampled_bit) | rx_ack_lim & (~sampled_bit) | rx_eof & (~sampled_bit) ); // Instantiation of the RX CRC module can_crc i_can_crc_rx ( .clk(clk), .data(sampled_bit), .enable(crc_enable & sample_point & (~bit_de_stuff)), .initialize(rx_eof), .crc(calculated_crc) ); assign no_byte0 = rtr1 | (data_len<1); assign no_byte1 = rtr1 | (data_len<2); can_acf i_can_acf ( .clk(clk), .rst(rst), .id(id), /* Mode register */ .reset_mode(reset_mode), .acceptance_filter_mode(acceptance_filter_mode), // Clock Divider register .extended_mode(extended_mode), /* This section is for BASIC and EXTENDED mode */ /* Acceptance code register */ .acceptance_code_0(acceptance_code_0), /* Acceptance mask register */ .acceptance_mask_0(acceptance_mask_0), /* End: This section is for BASIC and EXTENDED mode */ /* This section is for EXTENDED mode */ /* Acceptance code register */ .acceptance_code_1(acceptance_code_1), .acceptance_code_2(acceptance_code_2), .acceptance_code_3(acceptance_code_3), /* Acceptance mask register */ .acceptance_mask_1(acceptance_mask_1), .acceptance_mask_2(acceptance_mask_2), .acceptance_mask_3(acceptance_mask_3), /* End: This section is for EXTENDED mode */ .go_rx_crc_lim(go_rx_crc_lim), .go_rx_idle(go_rx_idle), .data0(tmp_fifo[0]), .data1(tmp_fifo[1]), .rtr1(rtr1), .rtr2(rtr2), .ide(ide), .no_byte0(no_byte0), .no_byte1(no_byte1), .id_ok(id_ok) ); assign header_len[2:0] = extended_mode ? (ide? (3'h5) : (3'h3)) : 3'h2; assign storing_header = header_cnt < header_len; assign limited_data_len_minus1[3:0] = remote_rq? 4'hf : ((data_len < 8)? (data_len -1'b1) : 4'h7); // - 1 because counter counts from 0 assign reset_wr_fifo = (data_cnt == (limited_data_len_minus1 + header_len)) | reset_mode; assign no_error = (~crc_error) & (~form_error) & (~stuff_error); // Write enable signal for 64-byte rx fifo always @ (posedge clk or posedge rst) begin if (rst) wr_fifo <= 1'b0; else if (reset_wr_fifo) wr_fifo <=#Tp 1'b0; else if (go_rx_inter & id_ok & (~error_frame_ended)) // FIX ME !!! Look following line // else if (go_rx_inter & id_ok & (~error_frame_ended) & (~tx_state)) FIX ME !!! This line is the correct one. The above line is for easier debugging only. wr_fifo <=#Tp 1'b1; end // Header counter. Header length depends on the mode of operation and frame format. always @ (posedge clk or posedge rst) begin if (rst) header_cnt <= 0; else if (reset_wr_fifo) header_cnt <=#Tp 0; else if (wr_fifo & storing_header) header_cnt <=#Tp header_cnt + 1; end // Data counter. Length of the data is limited to 8 bytes. always @ (posedge clk or posedge rst) begin if (rst) data_cnt <= 0; else if (reset_wr_fifo) data_cnt <=#Tp 0; else if (wr_fifo) data_cnt <=#Tp data_cnt + 1; end // Multiplexing data that is stored to 64-byte fifo depends on the mode of operation and frame format always @ (extended_mode or ide or data_cnt or header_cnt or header_len or storing_header or id or rtr1 or rtr2 or data_len or tmp_fifo[0] or tmp_fifo[2] or tmp_fifo[4] or tmp_fifo[6] or tmp_fifo[1] or tmp_fifo[3] or tmp_fifo[5] or tmp_fifo[7]) begin if (storing_header) begin if (extended_mode) // extended mode begin if (ide) // extended format begin case (header_cnt) // synthesis parallel_case 3'h0 : data_for_fifo <= {1'b1, rtr2, 2'h0, data_len}; 3'h1 : data_for_fifo <= id[28:21]; 3'h2 : data_for_fifo <= id[20:13]; 3'h3 : data_for_fifo <= id[12:5]; 3'h4 : data_for_fifo <= {id[4:0], 3'h0}; default: data_for_fifo <= 0; endcase end else // standard format begin case (header_cnt) // synthesis parallel_case 3'h0 : data_for_fifo <= {1'b0, rtr1, 2'h0, data_len}; 3'h1 : data_for_fifo <= id[10:3]; 3'h2 : data_for_fifo <= {id[2:0], 5'h0}; default: data_for_fifo <= 0; endcase end end else // normal mode begin case (header_cnt) // synthesis parallel_case 3'h0 : data_for_fifo <= id[10:3]; 3'h1 : data_for_fifo <= {id[2:0], rtr1, data_len}; default: data_for_fifo <= 0; endcase end end else data_for_fifo <= tmp_fifo[data_cnt-header_len]; end // Instantiation of the RX fifo module can_fifo i_can_fifo ( .clk(clk), .rst(rst), .wr(wr_fifo), .data_in(data_for_fifo), .addr(addr), .data_out(data_out), .reset_mode(reset_mode), .release_buffer(release_buffer), .extended_mode(extended_mode) ); // Transmitting error frame. The same counters are used for sending overload frame, too. always @ (posedge clk or posedge rst) begin if (rst) error_frame <= 1'b0; else if (reset_mode | error_frame_ended) error_frame <=#Tp 1'b0; else if (go_error_frame | go_overload_frame) error_frame <=#Tp 1'b1; end always @ (posedge clk or posedge rst) begin if (rst) error_cnt1 <= 1'b0; else if (reset_mode | error_frame_ended) error_cnt1 <=#Tp 1'b0; else if (error_frame & tx_point & (error_cnt1 < 6)) error_cnt1 <=#Tp error_cnt1 + 1'b1; end always @ (posedge clk or posedge rst) begin if (rst) enable_error_cnt2 <= 1'b0; else if (reset_mode | error_frame_ended) enable_error_cnt2 <=#Tp 1'b0; else if (sample_point & sampled_bit & (error_cnt1 == 6)) enable_error_cnt2 <=#Tp 1'b1; end always @ (posedge clk or posedge rst) begin if (rst) error_cnt2 <= 1'b0; else if (reset_mode | error_frame_ended) error_cnt2 <=#Tp 1'b0; else if (enable_error_cnt2 & tx_point) error_cnt2 <=#Tp error_cnt2 + 1'b1; end wire node_error_passive = 1; // FIX ME wire [18:0] basic_chain; wire [63:0] basic_chain_data; wire [18:0] extended_chain_std; wire [38:0] extended_chain_ext; wire [63:0] extended_chain_data; wire rst_tx_pointer; wire [7:0] r_tx_data_0; wire [7:0] r_tx_data_1; wire [7:0] r_tx_data_2; wire [7:0] r_tx_data_3; wire [7:0] r_tx_data_4; wire [7:0] r_tx_data_5; wire [7:0] r_tx_data_6; wire [7:0] r_tx_data_7; wire [7:0] r_tx_data_8; wire [7:0] r_tx_data_9; wire [7:0] r_tx_data_10; wire [7:0] r_tx_data_11; wire [7:0] r_tx_data_12; always @ (posedge clk or posedge rst) begin if (rst) tx <= 1'b1; else if (reset_mode | error_frame_ended) // Reset tx <=#Tp 1'b1; else if (tx_point) begin if (tx_state) // Transmitting message tx <=#Tp ((~bit_de_stuff_tx) & tx_bit) | (bit_de_stuff_tx & (~tx_q)); else if ((~tx_state) & rx_ack & no_error) // Acknowledge tx <=#Tp 1'b0; else if (error_frame) // Transmitting error frame begin if (error_cnt1 < 6) begin if (node_error_passive) tx <=#Tp 1'b1; else tx <=#Tp 1'b0; end else if (error_cnt2 < 7) tx <=#Tp 1'b1; end else tx <=#Tp 1'b1; end end always @ (posedge clk) begin if (tx_point) tx_q <=#Tp tx; end /* Delayed tx point */ always @ (posedge clk) begin tx_point_q <=#Tp tx_point; end /* Changing bit order from [7:0] to [0:7] */ can_ibo i_ibo_tx_data_0 (.di(tx_data_0), .do(r_tx_data_0)); can_ibo i_ibo_tx_data_1 (.di(tx_data_1), .do(r_tx_data_1)); can_ibo i_ibo_tx_data_2 (.di(tx_data_2), .do(r_tx_data_2)); can_ibo i_ibo_tx_data_3 (.di(tx_data_3), .do(r_tx_data_3)); can_ibo i_ibo_tx_data_4 (.di(tx_data_4), .do(r_tx_data_4)); can_ibo i_ibo_tx_data_5 (.di(tx_data_5), .do(r_tx_data_5)); can_ibo i_ibo_tx_data_6 (.di(tx_data_6), .do(r_tx_data_6)); can_ibo i_ibo_tx_data_7 (.di(tx_data_7), .do(r_tx_data_7)); can_ibo i_ibo_tx_data_8 (.di(tx_data_8), .do(r_tx_data_8)); can_ibo i_ibo_tx_data_9 (.di(tx_data_9), .do(r_tx_data_9)); can_ibo i_ibo_tx_data_10 (.di(tx_data_10), .do(r_tx_data_10)); can_ibo i_ibo_tx_data_11 (.di(tx_data_11), .do(r_tx_data_11)); can_ibo i_ibo_tx_data_12 (.di(tx_data_12), .do(r_tx_data_12)); /* Changing bit order from [14:0] to [0:14] */ can_ibo i_calculated_crc0 (.di(calculated_crc[14:7]), .do(r_calculated_crc[7:0])); can_ibo i_calculated_crc1 (.di({calculated_crc[6:0], 1'b0}), .do(r_calculated_crc[15:8])); assign basic_chain = {r_tx_data_1[7:4], 2'h0, r_tx_data_1[3:0], r_tx_data_0[7:0], 1'b0}; assign basic_chain_data = {r_tx_data_9, r_tx_data_8, r_tx_data_7, r_tx_data_6, r_tx_data_5, r_tx_data_4, r_tx_data_3, r_tx_data_2}; assign extended_chain_std = {r_tx_data_0[7:4], 2'h0, r_tx_data_0[1], r_tx_data_2[2:0], r_tx_data_1[7:0], 1'b0}; assign extended_chain_ext = {r_tx_data_0[7:4], 2'h0, r_tx_data_0[1], r_tx_data_4[4:0], r_tx_data_3[7:0], r_tx_data_2[7:3], 1'b1, 1'b1, r_tx_data_2[2:0], r_tx_data_1[7:0], 1'b0}; assign extended_chain_data = {r_tx_data_12, r_tx_data_11, r_tx_data_10, r_tx_data_9, r_tx_data_8, r_tx_data_7, r_tx_data_6, r_tx_data_5}; always @ (extended_mode or rx_data or tx_pointer or extended_chain_data or rx_crc or r_calculated_crc or r_tx_data_0 or extended_chain_ext or extended_chain_std or basic_chain_data or basic_chain or finish_msg) begin if (extended_mode) begin if (rx_data) // data stage tx_bit = extended_chain_data[tx_pointer]; else if (rx_crc) tx_bit = r_calculated_crc[tx_pointer]; else if (finish_msg) tx_bit = 1'b1; else begin if (r_tx_data_0[0]) // Extended frame tx_bit = extended_chain_ext[tx_pointer]; else tx_bit = extended_chain_std[tx_pointer]; end end else // Basic mode begin if (rx_data) // data stage tx_bit = basic_chain_data[tx_pointer]; else if (rx_crc) tx_bit = r_calculated_crc[tx_pointer]; else if (finish_msg) tx_bit = 1'b1; else tx_bit = basic_chain[tx_pointer]; end end assign rst_tx_pointer = ((~bit_de_stuff_tx) & tx_point & (~rx_data) & extended_mode & tx_pointer == 38 ) | // arbitration + control for extended format ((~bit_de_stuff_tx) & tx_point & (~rx_data) & (~extended_mode) & tx_pointer == 18 ) | // arbitration + control for standard format ((~bit_de_stuff_tx) & tx_point & rx_data & extended_mode & tx_pointer == (8 * tx_data_0[3:0] - 1)) | // data ((~bit_de_stuff_tx) & tx_point & rx_data & (~extended_mode) & tx_pointer == (8 * tx_data_1[3:0] - 1)) | // data ( tx_point & rx_crc_lim ) | // crc (go_rx_idle ) | // at the end (reset_mode ) | (error_frame ) ; // FIX ME (not sure this is ok) always @ (posedge clk or posedge rst) begin if (rst) tx_pointer <= 'h0; else if (rst_tx_pointer) tx_pointer <=#Tp 'h0; else if (go_early_tx | (tx_point & tx_state & (~bit_de_stuff_tx))) tx_pointer <=#Tp tx_pointer + 1'b1; end wire rst_need_to_tx = go_rx_inter & (~error_frame) & (~priority_lost); always @ (posedge clk or posedge rst) begin if (rst) need_to_tx <= 1'b0; else if (rst_need_to_tx) need_to_tx <=#Tp 'h0; else if (tx_request) need_to_tx <=#Tp 1'b1; end assign go_early_tx = need_to_tx & (~tx_state) & sample_point & (~sampled_bit) & (rx_idle | rx_inter & (bit_cnt == 2)); assign go_tx = need_to_tx & (~tx_state) & sample_point & (go_early_tx | sampled_bit & rx_idle); // Tx state always @ (posedge clk or posedge rst) begin if (rst) tx_state <= 1'b0; else if (go_rx_inter | error_frame | priority_lost) tx_state <=#Tp 1'b0; else if (go_tx) tx_state <=#Tp 1'b1; end // transmitting signals that core is a transmitter. No synchronization is done meanwhile. always @ (posedge clk or posedge rst) begin if (rst) transmitting <= 1'b0; else if (go_rx_idle | reset_mode | priority_lost) // FIX ME !!! This line might not be ok. transmitting <=#Tp 1'b0; else if (~no_error | go_tx) transmitting <=#Tp 1'b1; end always @ (posedge clk or posedge rst) begin if (rst) finish_msg <= 1'b0; else if (go_rx_idle | error_frame | reset_mode) finish_msg <=#Tp 1'b0; else if (go_rx_crc_lim) finish_msg <=#Tp 1'b1; end always @ (posedge clk or posedge rst) begin if (rst) priority_lost <= 1'b0; else if (go_rx_idle | error_frame | reset_mode) priority_lost <=#Tp 1'b0; else if (tx_state & sample_point & tx & (rx_id1 | rx_rtr1 | rx_id2 | rx_ide | rx_id2 | rx_rtr2)) priority_lost <=#Tp (~sampled_bit); end endmodule
Go to most recent revision | Compare with Previous | Blame | View Log