OpenCores
URL https://opencores.org/ocsvn/can/can/trunk

Subversion Repositories can

[/] [can/] [tags/] [rel_6/] [rtl/] [verilog/] [can_bsp.v] - Rev 30

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                     ////
////                                                              ////
//// The CAN protocol is developed by Robert Bosch GmbH and       ////
//// protected by patents. Anybody who wants to implement this    ////
//// CAN IP core on silicon has to obtain a CAN protocol license  ////
//// from Bosch.                                                  ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.19  2003/02/09 18:40:29  mohor
// Overload fixed. Hard synchronization also enabled at the last bit of
// interframe.
//
// Revision 1.18  2003/02/09 02:24:33  mohor
// Bosch license warning added. Error counters finished. Overload frames
// still need to be fixed.
//
// Revision 1.17  2003/02/04 17:24:41  mohor
// Backup.
//
// 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,
  last_bit_of_inter,
 
  /* 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,
  tx_oen
 
);
 
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;
output        last_bit_of_inter;
 
 
/* 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;
output        tx_oen;
 
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           tx_point_q;
 
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;
reg     [2:0] passive_cnt;
 
reg           transmitting;
 
reg           error_frame;
reg           error_frame_q;
reg           enable_error_cnt2;
reg     [2:0] error_cnt1;
reg     [2:0] error_cnt2;
reg     [2:0] delayed_dominant_cnt;
reg           enable_overload_cnt2;
reg           overload_frame;
reg           overload_frame_blocked;
reg     [2:0] overload_cnt1;
reg     [2:0] overload_cnt2;
reg           tx;
reg           crc_err;
 
reg           priority_lost;
reg           tx_q;
 
reg           need_to_tx;   // When the CAN core has something to transmit and a dominant bit is sampled at the third bit
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           transmitter;
reg           finish_msg;
 
reg     [9:0] rx_err_cnt;
reg     [9:0] tx_err_cnt;
reg           rx_err_cnt_blocked;
reg    [10:0] recessive_cnt;
 
reg           node_error_passive;
reg           node_bus_off;
reg           ack_err_latched;
reg           bit_err_latched;
reg           stuff_err_latched;
reg           form_err_latched;
reg           rule5;
reg           rule3_exc1_1;
reg           rule3_exc1_2;
reg           rule3_exc2;
reg           suspend;
reg           susp_cnt_en;
reg     [2:0] susp_cnt;
reg           go_error_frame_q;
reg           error_flag_over_blocked;
 
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;
 
wire   [14:0] calculated_crc;
wire   [15:0] r_calculated_crc;
wire          remote_rq;
wire    [3:0] limited_data_len;
wire          form_err;
wire          set_form_error;
 
wire          error_frame_ended;
wire          overload_frame_ended;
wire          bit_err;
wire          ack_err;
wire          stuff_err;
                                    // 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.
 
wire    [2:0] header_len;
wire          storing_header;
wire    [3:0] limited_data_len_minus1;
wire          reset_wr_fifo;
wire          err;
 
wire          tx_successful;
wire          recessive_cnt_ok;
wire          arbitration_field;
 
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;
 
wire          send_ack;
wire          bit_err_exc1;
wire          bit_err_exc2;
wire          bit_err_exc3;
wire          bit_err_exc4;
wire          bit_err_exc5;
wire          error_flag_over;
wire          overload_flag_over;
 
 
assign go_rx_idle     =                   sample_point &  sampled_bit & last_bit_of_inter;
assign go_rx_id1      =                   sample_point &  (~sampled_bit) & (rx_idle | last_bit_of_inter);
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_frame_ended) & (~overload_needed);
 
assign go_error_frame = (form_err | stuff_err | bit_err | ack_err | (crc_err & go_rx_eof));
assign error_frame_ended = (error_cnt2 == 7) & tx_point;
assign overload_frame_ended = (overload_cnt2 == 7) & tx_point;
 
assign go_overload_frame = (   ((sample_point &  rx_eof  & (eof_cnt == 6)) | error_frame_ended | overload_frame_ended) & overload_needed | 
                               sample_point & (~sampled_bit) & rx_inter & (bit_cnt < 2)                                                  |
                               sample_point & (~sampled_bit) & ((error_cnt2 == 7) | (overload_cnt2 == 7))
                           )
                           & (~overload_frame_blocked)
                           ;
 
 
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 | go_overload_frame;
 
assign remote_rq = ((~ide) & rtr1) | (ide & rtr2);
assign limited_data_len = (data_len < 8)? data_len : 4'h8;
 
assign ack_err = rx_ack & sample_point & sampled_bit & tx_state;
assign bit_err = (tx_state | error_frame | overload_frame | rx_ack) & sample_point & (tx !== sampled_bit) & (~bit_err_exc1) & (~bit_err_exc2) & (~bit_err_exc3) & (~bit_err_exc4) & (~bit_err_exc5);
assign bit_err_exc1 = tx_state & arbitration_field & tx;
assign bit_err_exc2 = rx_ack & tx;
assign bit_err_exc3 = error_frame & node_error_passive & (error_cnt1 < 7);
assign bit_err_exc4 = (error_frame & (error_cnt1 == 7) & (~enable_error_cnt2)) | (overload_frame & (overload_cnt1 == 7) & (~enable_overload_cnt2));
assign bit_err_exc5 = (error_frame & (error_cnt2 == 7)) | (overload_frame & (overload_cnt2 == 7));
 
assign arbitration_field = rx_id1 | rx_rtr1 | rx_ide | rx_id2 | rx_rtr2;
 
assign last_bit_of_inter = rx_inter & (bit_cnt == 2);
 
 
// 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 | go_overload_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 (go_rx_inter | go_error_frame | go_overload_frame)
        eof_cnt <=#Tp 0;
      else if (rx_eof)
        eof_cnt <=#Tp eof_cnt + 1'b1;
    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_err
assign stuff_err = sample_point & bit_stuff_cnt_en & bit_de_stuff & (sampled_bit == sampled_bit_q);
 
 
 
// 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_err <= 1'b0;
  else if (go_rx_ack)
    crc_err <=#Tp crc_in != calculated_crc;
  else if (reset_mode | error_frame_ended)
    crc_err <=#Tp 1'b0;
end
 
 
// Conditions for form error
assign form_err = sample_point & ( ((~bit_de_stuff) & rx_ide     &   sampled_bit & (~rtr1)      ) |
                                   (                  rx_crc_lim & (~sampled_bit)               ) |
                                   (                  rx_ack_lim & (~sampled_bit)               ) |
                                   ((eof_cnt < 6)   & rx_eof     & (~sampled_bit) & (~tx_state) ) |
                                   (                & rx_eof     & (~sampled_bit) &   tx_state  )
                                 );
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    ack_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    ack_err_latched <=#Tp 1'b0;
  else if (ack_err)
    ack_err_latched <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    bit_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    bit_err_latched <=#Tp 1'b0;
  else if (bit_err)
    bit_err_latched <=#Tp 1'b1;
end
 
 
// Rule 5 (Fault confinement).
always @ (posedge clk or posedge rst)
begin
  if (rst)
    rule5 <= 1'b0;
  else if (reset_mode | error_flag_over)
    rule5 <=#Tp 1'b0;
  else if ((~node_error_passive) & bit_err & (~bit_err_latched) &  (error_frame    & (error_cnt1    < 7) | 
                                                                    overload_frame & (overload_cnt1 < 7) )
          )
    rule5 <=#Tp 1'b1;
end
 
 
// Rule 3 exception 1 - first part (Fault confinement).
always @ (posedge clk or posedge rst)
begin
  if (rst)
    rule3_exc1_1 <= 1'b0;
  else if (reset_mode | error_flag_over | rule3_exc1_2)
    rule3_exc1_1 <=#Tp 1'b0;
  else if (transmitter & node_error_passive & ack_err)
    rule3_exc1_1 <=#Tp 1'b1;
end
 
 
// Rule 3 exception 1 - second part (Fault confinement).
always @ (posedge clk or posedge rst)
begin
  if (rst)
    rule3_exc1_2 <= 1'b0;
  else if (reset_mode | error_flag_over)
    rule3_exc1_2 <=#Tp 1'b0;
  else if (rule3_exc1_1)
    rule3_exc1_2 <=#Tp 1'b1;
  else if ((error_cnt1 < 7) & sample_point & (~sampled_bit))
    rule3_exc1_2 <=#Tp 1'b0;
end
 
 
// Rule 3 exception 2 (Fault confinement).
always @ (posedge clk or posedge rst)
begin
  if (rst)
    rule3_exc2 <= 1'b0;
  else if (reset_mode | error_flag_over)
    rule3_exc2 <=#Tp 1'b0;
  else if (transmitter & stuff_err & arbitration_field & sample_point & tx & (~sampled_bit))
    rule3_exc2 <=#Tp 1'b1;
end
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    stuff_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    stuff_err_latched <=#Tp 1'b0;
  else if (stuff_err)
    stuff_err_latched <=#Tp 1'b1;
end
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    form_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    form_err_latched <=#Tp 1'b0;
  else if (form_err)
    form_err_latched <=#Tp 1'b1;
end
 
 
 
// 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 | go_error_frame | go_overload_frame),
  .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_inter(go_rx_inter),
  .go_error_frame(go_error_frame),
 
  .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 err = form_err | stuff_err | bit_err | ack_err | form_err_latched | stuff_err_latched | bit_err_latched | ack_err_latched | crc_err;
 
 
 
// 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.
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_frame <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    error_frame <=#Tp 1'b0;
  else if (go_error_frame)
    error_frame <=#Tp 1'b1;
end
 
 
always @ (posedge clk)
begin
  if (sample_point)
    error_frame_q <=#Tp error_frame;
end
 
 
always @ (posedge clk)
begin
    go_error_frame_q <=#Tp go_error_frame;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_cnt1 <= 1'b0;
  else if (reset_mode | error_frame_ended | go_error_frame | go_overload_frame)
    error_cnt1 <=#Tp 1'b0;
  else if (error_frame & tx_point & (error_cnt1 < 7))
    error_cnt1 <=#Tp error_cnt1 + 1'b1;
end
 
 
 
assign error_flag_over = ((~node_error_passive) & sample_point & (error_cnt1 == 7) | node_error_passive  & sample_point & (passive_cnt == 5)) & (~enable_error_cnt2);
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_flag_over_blocked <= 1'b0;
  else if (reset_mode | error_frame_ended | go_error_frame | go_overload_frame)
    error_flag_over_blocked <=#Tp 1'b0;
  else if (error_flag_over)
    error_flag_over_blocked <=#Tp 1'b1;
end
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    enable_error_cnt2 <= 1'b0;
  else if (reset_mode | error_frame_ended | go_error_frame | go_overload_frame)
    enable_error_cnt2 <=#Tp 1'b0;
  else if (error_frame & (error_flag_over & sampled_bit))
    enable_error_cnt2 <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_cnt2 <= 0;
  else if (reset_mode | error_frame_ended | go_error_frame | go_overload_frame)
    error_cnt2 <=#Tp 0;
  else if (enable_error_cnt2 & tx_point)
    error_cnt2 <=#Tp error_cnt2 + 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    delayed_dominant_cnt <= 0;
  else if (reset_mode | enable_error_cnt2 | go_error_frame | enable_overload_cnt2 | go_overload_frame)
    delayed_dominant_cnt <=#Tp 0;
  else if (sample_point & (~sampled_bit) & ((error_cnt1 == 7) | (overload_cnt1 == 7)))
    delayed_dominant_cnt <=#Tp delayed_dominant_cnt + 1'b1;
end
 
 
// passive_cnt
always @ (posedge clk or posedge rst)
begin
  if (rst)
    passive_cnt <= 0;
  else if (reset_mode | error_frame_ended | go_error_frame | go_overload_frame)
    passive_cnt <=#Tp 0;
  else if (sample_point & (passive_cnt < 5))
    begin
      if (error_frame_q & (~enable_error_cnt2) & (sampled_bit == sampled_bit_q))
        passive_cnt <=#Tp passive_cnt + 1'b1;
      else
        passive_cnt <=#Tp 0;
    end
end
 
 
 
// Transmitting overload frame.
always @ (posedge clk or posedge rst)
begin
  if (rst)
    overload_frame <= 1'b0;
  else if (reset_mode | overload_frame_ended | go_error_frame)
    overload_frame <=#Tp 1'b0;
  else if (go_overload_frame)
    overload_frame <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    overload_cnt1 <= 1'b0;
  else if (reset_mode | overload_frame_ended | go_error_frame | go_overload_frame)
    overload_cnt1 <=#Tp 1'b0;
  else if (overload_frame & tx_point & (overload_cnt1 < 7))
    overload_cnt1 <=#Tp overload_cnt1 + 1'b1;
end
 
 
assign overload_flag_over = sample_point & (overload_cnt1 == 7) & (~enable_overload_cnt2);
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    enable_overload_cnt2 <= 1'b0;
  else if (reset_mode | overload_frame_ended | go_error_frame | go_overload_frame)
    enable_overload_cnt2 <=#Tp 1'b0;
  else if (overload_frame & (overload_flag_over & sampled_bit))
    enable_overload_cnt2 <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    overload_cnt2 <= 0;
  else if (reset_mode | overload_frame_ended | go_error_frame | go_overload_frame)
    overload_cnt2 <=#Tp 0;
  else if (enable_overload_cnt2 & tx_point)
    overload_cnt2 <=#Tp overload_cnt2 + 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    overload_frame_blocked <= 0;
  else if (reset_mode | go_error_frame | go_rx_id1)
    overload_frame_blocked <=#Tp 0;
  else if (go_overload_frame & overload_frame)            // This is a second sequential overload
    overload_frame_blocked <=#Tp 1'b1;
end
 
 
assign send_ack = (~tx_state) & rx_ack & (~err);
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    tx <= 1'b1;
  else if (reset_mode)                                                          // 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 (send_ack)                                                        // Acknowledge
        tx <=#Tp 1'b0;
      else if (overload_frame)                                                  // Transmitting overload frame
        begin
          if (overload_cnt1 < 6)
            tx <=#Tp 1'b0;
          else
            tx <=#Tp 1'b1;
        end
      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
            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                                                                                            ) |
                        (overload_frame                                                                                        ) |
                        (error_frame                                                                                           ) ;
 
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
 
 
assign tx_successful = transmitter & go_rx_inter & (~error_frame_ended) & (~overload_frame_ended) & (~priority_lost);
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    need_to_tx <= 1'b0;
  else if (tx_successful | node_bus_off)
    need_to_tx <=#Tp 1'h0;
  else if (tx_request)
    need_to_tx <=#Tp 1'b1;
end
 
 
 
assign go_early_tx = need_to_tx & (~tx_state) & (~suspend) & sample_point & (~sampled_bit) & (rx_idle | last_bit_of_inter);
assign go_tx       = need_to_tx & (~tx_state) & (~suspend) & (go_early_tx | 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
 
 
 
// Node is a transmitter
always @ (posedge clk or posedge rst)
begin
  if (rst)
    transmitter <= 1'b0;
  else if (go_tx)
    transmitter <=#Tp 1'b1;
  else if (go_rx_inter)
    transmitter <=#Tp 1'b0;
end
 
 
 
// Signal "transmitting" signals that the core is a transmitting (message, error frame or overload frame). No synchronization is done meanwhile.
// Node might be both transmitter or receiver (sending error or overload frame)
always @ (posedge clk or posedge rst)
begin
  if (rst)
    transmitting <= 1'b0;
  else if (go_error_frame | go_overload_frame | go_tx)
    transmitting <=#Tp 1'b1;
  else if (reset_mode | go_rx_idle | (go_rx_id1 & (~tx_state)) | (priority_lost & tx_state))
    transmitting <=#Tp 1'b0;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    suspend <= 0;
  else if (reset_mode | (sample_point & (susp_cnt == 7)))
    suspend <=#Tp 0;
  else if (go_rx_inter & transmitter & node_error_passive)
    suspend <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    susp_cnt_en <= 0;
  else if (reset_mode | (sample_point & (susp_cnt == 7)))
    susp_cnt_en <=#Tp 0;
  else if (suspend & sample_point & last_bit_of_inter)
    susp_cnt_en <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    susp_cnt <= 0;
  else if (reset_mode | (sample_point & (susp_cnt == 7)))
    susp_cnt <=#Tp 0;
  else if (susp_cnt_en & sample_point)
    susp_cnt <=#Tp susp_cnt + 1'b1;
end
 
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    finish_msg <= 1'b0;
  else if (go_rx_idle | go_rx_id1 | 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 & arbitration_field)
    priority_lost <=#Tp (~sampled_bit);
end
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    rx_err_cnt <= 'h0;
  else if (reset_mode)
    rx_err_cnt <=#Tp 'h0;
  else
    begin
      if ((~transmitter) & go_rx_ack_lim & (~err) & (rx_err_cnt > 0))
        begin
          if (rx_err_cnt > 127)
            rx_err_cnt <=#Tp 127;
          else
            rx_err_cnt <=#Tp rx_err_cnt - 1'b1;
        end
      else if ((rx_err_cnt < 1023) & (~transmitter))
        begin
          if (go_error_frame_q & (~rule5))                                                                          // 1  (rule 5 is just the opposite then rule 1 exception
            rx_err_cnt <=#Tp rx_err_cnt + 1'b1;
          else if ( (error_frame & sample_point & (~sampled_bit) & (error_cnt1 == 7) & (~rx_err_cnt_blocked)  ) |   // 2
                    (go_error_frame_q & rule5                                                                 ) |   // 5
                    (error_frame & sample_point & (~sampled_bit) & (delayed_dominant_cnt == 7)                )     // 6
                  )
            rx_err_cnt <=#Tp rx_err_cnt + 4'h8;
        end
    end
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    tx_err_cnt <= 'h0;
  else if (reset_mode | node_bus_off)
    tx_err_cnt <=#Tp 'h0;
  else
    begin
      if ((tx_err_cnt > 0) & tx_successful)
        tx_err_cnt <=#Tp tx_err_cnt - 1'h1;
      else if ((tx_err_cnt < 1023) & transmitter)
        begin
          if ( (sample_point & (~sampled_bit) & (delayed_dominant_cnt == 7)                     ) |       // 6
               (error_flag_over & (~error_flag_over_blocked) & rule5                            ) |       // 4  (rule 5 is the same as rule 4)
               (error_flag_over & (~error_flag_over_blocked) & (~rule3_exc1_2) & (~rule3_exc2)  )         // 3
             )
            tx_err_cnt <=#Tp tx_err_cnt + 4'h8;
        end
    end
end
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    rx_err_cnt_blocked <= 1'b0;
  else if (reset_mode | error_frame_ended)
    rx_err_cnt_blocked <=#Tp 1'b0;
  else if (sample_point & (error_cnt1 == 7))
    rx_err_cnt_blocked <=#Tp 1'b1;
end
 
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    node_error_passive <= 1'b0;
  else if (reset_mode | node_bus_off | ((rx_err_cnt < 128) & (tx_err_cnt < 128) & error_frame_ended))
    node_error_passive <=#Tp 1'b0;
  else if (((rx_err_cnt >= 128) | (tx_err_cnt >= 128)) & error_frame_ended)
    node_error_passive <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    node_bus_off <= 1'b0;
  else if (reset_mode | ((rx_err_cnt == 0) & (tx_err_cnt == 0) & recessive_cnt_ok))
    node_bus_off <=#Tp 1'b0;
  else if (tx_err_cnt >= 256)
    node_bus_off <=#Tp 1'b1;
end
 
 
always @ (posedge clk or posedge rst)
begin
  if (rst)
    recessive_cnt <= 1'b0;
  else if (sample_point)
    begin
      if (node_bus_off & sampled_bit)
        recessive_cnt <=#Tp recessive_cnt + 1'b1;
      else
        recessive_cnt <=#Tp 0;
    end
end
 
 
assign recessive_cnt_ok = recessive_cnt == 128 * 11;
 
 
assign tx_oen = node_bus_off;
 
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.