⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can_bsp.v

📁 人民邮电出版社出版的《FPGA硬件接口设计实践》一书的代码
💻 V
📖 第 1 页 / 共 4 页
字号:
  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).
assign rule5 = (~node_error_passive) & bit_err &  (error_frame    & (error_cnt1    < 7) | 
                                                   overload_frame & (overload_cnt1 < 7) );

// 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(go_crc_enable),
  .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) & ((~tx_state) | self_rx_request))
    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),
  .fifo_selected(fifo_selected),

  .reset_mode(reset_mode),
  .release_buffer(release_buffer),
  .extended_mode(extended_mode),
  .overrun(overrun),
  .info_empty(info_empty),
  .info_cnt(rx_message_counter)
);


// 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 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) & (~listen_only_mode);


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 & (~go_early_tx_latched);
end


/* Delayed tx point */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -