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

📄 can_bsp.v

📁 人民邮电出版社出版的《FPGA硬件接口设计实践》一书的代码
💻 V
📖 第 1 页 / 共 4 页
字号:
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  &   r_tx_data_0[0]   & tx_pointer == 38                      ) |   // arbitration + control for extended format
                        ((~bit_de_stuff_tx) & tx_point & (~rx_data) &   extended_mode  & (~r_tx_data_0[0])  & tx_pointer == 18                      ) |   // 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) & (~arbitration_lost) | single_shot_transmission);


always @ (posedge clk or posedge rst)
begin
  if (rst)
    need_to_tx <= 1'b0;
  else if (tx_successful | reset_mode | (abort_tx & (~transmitting)))
    need_to_tx <=#Tp 1'h0;
  else if (tx_request & sample_point)
    need_to_tx <=#Tp 1'b1;
end



assign go_early_tx = (~listen_only_mode) & need_to_tx & (~tx_state) & (~suspend) & sample_point & (~sampled_bit) & (rx_idle | last_bit_of_inter);
assign go_tx       = (~listen_only_mode) & need_to_tx & (~tx_state) & (~suspend) & (go_early_tx | rx_idle);


// go_early_tx latched (for proper bit_de_stuff generation)
always @ (posedge clk or posedge rst)
begin
  if (rst)
    go_early_tx_latched <= 1'b0;
  else if (tx_point_q)
    go_early_tx_latched <=#Tp 1'b0;
  else if (go_early_tx)
    go_early_tx_latched <=#Tp 1'b1;
end



// Tx state
always @ (posedge clk or posedge rst)
begin
  if (rst)
    tx_state <= 1'b0;
  else if (reset_mode | go_rx_inter | error_frame | arbitration_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 (reset_mode | 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)) | (arbitration_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)
    arbitration_lost <= 1'b0;
  else if (go_rx_idle | error_frame | reset_mode)
    arbitration_lost <=#Tp 1'b0;
  else if (tx_state & sample_point & tx & arbitration_field)
    arbitration_lost <=#Tp (~sampled_bit);
end


always @ (posedge clk)
begin
  arbitration_lost_q <=#Tp arbitration_lost;
end


assign set_arbitration_lost_irq = arbitration_lost & (~arbitration_lost_q) & (~arbitration_blocked);


always @ (posedge clk or posedge rst)
begin
  if (rst)
    arbitration_cnt_en <= 1'b0;
  else if (arbitration_blocked)
    arbitration_cnt_en <=#Tp 1'b0;
  else if (rx_id1 & sample_point & (~arbitration_blocked))
    arbitration_cnt_en <=#Tp 1'b1;
end



always @ (posedge clk or posedge rst)
begin
  if (rst)
    arbitration_blocked <= 1'b0;
  else if (read_arbitration_lost_capture_reg)
    arbitration_blocked <=#Tp 1'b0;
  else if (set_arbitration_lost_irq)
    arbitration_blocked <=#Tp 1'b1;
end


always @ (posedge clk or posedge rst)
begin
  if (rst)
    arbitration_lost_capture <= 5'h0;
  else if (read_arbitration_lost_capture_reg)
    arbitration_lost_capture <=#Tp 5'h0;
  else if (sample_point & (~arbitration_blocked) & arbitration_cnt_en & (~bit_de_stuff))
    arbitration_lost_capture <=#Tp arbitration_lost_capture + 1'b1;
end



always @ (posedge clk or posedge rst)
begin
  if (rst)
    rx_err_cnt <= 'h0;
  else if (we_rx_err_cnt & (~node_bus_off))
    rx_err_cnt <=#Tp {1'b0, data_in};
  else if (set_reset_mode)
    rx_err_cnt <=#Tp 'h0;
  else
    begin
      if (~listen_only_mode)
        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 < 248) & (~transmitter))   // 248 + 8 = 256
            begin
              if (go_error_frame & (~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 & 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
end


always @ (posedge clk or posedge rst)
begin
  if (rst)
    tx_err_cnt <= 'h0;
  else if (we_tx_err_cnt)
    tx_err_cnt <=#Tp {1'b0, data_in};
  else
    begin
      if (set_reset_mode)
        tx_err_cnt <=#Tp 127;
      else if ((tx_err_cnt > 0) & (tx_successful | bus_free))
        tx_err_cnt <=#Tp tx_err_cnt - 1'h1;
      else if (transmitter)
        begin
          if ( (sample_point & (~sampled_bit) & (delayed_dominant_cnt == 7)                     ) |       // 6
               (go_error_frame & 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 ((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 | go_error_frame | (~reset_mode) & reset_mode_q) & (~node_bus_off))
    node_error_passive <=#Tp 1'b1;
end


assign node_error_active = ~(node_error_passive | node_bus_off);


always @ (posedge clk or posedge rst)
begin
  if (rst)
    node_bus_off <= 1'b0;
  else if ((rx_err_cnt == 0) & (tx_err_cnt == 0) & (~reset_mode) | (we_tx_err_cnt & (data_in < 255)))
    node_bus_off <=#Tp 1'b0;
  else if ((tx_err_cnt >= 256) | (we_tx_err_cnt & (data_in == 255)))
    node_bus_off <=#Tp 1'b1;
end



always @ (posedge clk or posedge rst)
begin
  if (rst)
    bus_free_cnt <= 0;
  else if (reset_mode)
    bus_free_cnt <=#Tp 0;
  else if (sample_point)
    begin
      if (sampled_bit & bus_free_cnt_en & (bus_free_cnt < 10))
        bus_free_cnt <=#Tp bus_free_cnt + 1'b1;
      else
        bus_free_cnt <=#Tp 0;
    end
end


always @ (posedge clk or posedge rst)
begin
  if (rst)
    bus_free_cnt_en <= 1'b0;
  else if ((~reset_mode) & reset_mode_q | node_bus_off_q & (~reset_mode))
    bus_free_cnt_en <=#Tp 1'b1;
  else if (sample_point &  (bus_free_cnt==10) & (~node_bus_off))
    bus_free_cnt_en <=#Tp 1'b0;
end


always @ (posedge clk or posedge rst)
begin
  if (rst)
    bus_free <= 1'b0;
  else if (sample_point & sampled_bit & (bus_free_cnt==10))
    bus_free <=#Tp 1'b1;
  else
    bus_free <=#Tp 1'b0;
end


always @ (posedge clk or posedge rst)
begin
  if (rst)
    waiting_for_bus_free <= 1'b1;
  else if (bus_free & (~node_bus_off))
    waiting_for_bus_free <=#Tp 1'b0;
  else if ((~reset_mode) & reset_mode_q | node_bus_off_q & (~reset_mode))
    waiting_for_bus_free <=#Tp 1'b1;
end


assign tx_oen = node_bus_off;

assign set_reset_mode = node_bus_off & (~node_bus_off_q);
assign error_status = (~reset_mode) & extended_mode? ((rx_err_cnt >= error_warning_limit) | (tx_err_cnt >= error_warning_limit))    :
                                                     ((rx_err_cnt >= 96) | (tx_err_cnt >= 96))                                      ;

assign transmit_status = transmitting                 | (extended_mode & waiting_for_bus_free);
assign receive_status  = (~rx_idle) & (~transmitting) | (extended_mode & waiting_for_bus_free);


/* Error code capture register */
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_capture_code <= 8'h0;
  else if (read_error_code_capture_reg)
    error_capture_code <=#Tp 8'h0;
  else if (set_bus_error_irq)
    error_capture_code <=#Tp {error_capture_code_type[7:6], error_capture_code_direction, error_capture_code_segment[4:0]};
end



assign error_capture_code_segment[0] = rx_idle | rx_ide | (rx_id2 & (bit_cnt<13)) | rx_r1 | rx_r0 | rx_dlc | rx_ack | rx_ack_lim | error_frame & node_error_active;
assign error_capture_code_segment[1] = rx_idle | rx_id1 | rx_id2 | rx_dlc | rx_data | rx_ack_lim | rx_eof | rx_inter | error_frame & node_error_passive;
assign error_capture_code_segment[2] = (rx_id1 & (bit_cnt>7)) | rx_rtr1 | rx_ide | rx_id2 | rx_rtr2 | rx_r1 | error_frame & node_error_passive | overload_frame;
assign error_capture_code_segment[3] = (rx_id2 & (bit_cnt>4)) | rx_rtr2 | rx_r1 | rx_r0 | rx_dlc | rx_data | rx_crc | rx_crc_lim | rx_ack | rx_ack_lim | rx_eof | overload_frame;
assign error_capture_code_segment[4] = rx_crc_lim | rx_ack | rx_ack_lim | rx_eof | rx_inter | error_frame | overload_frame;
assign error_capture_code_direction  = ~transmitting;


always @ (bit_err or form_err or stuff_err)
begin
  if (bit_err)
    error_capture_code_type[7:6] <= 2'b00;
  else if (form_err)
    error_capture_code_type[7:6] <= 2'b01;
  else if (stuff_err)
    error_capture_code_type[7:6] <= 2'b10;
  else
    error_capture_code_type[7:6] <= 2'b11;
end


assign set_bus_error_irq = go_error_frame & (~error_capture_code_blocked);


always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_capture_code_blocked <= 1'b0;
  else if (read_error_code_capture_reg)
    error_capture_code_blocked <=#Tp 1'b0;
  else if (set_bus_error_irq)
    error_capture_code_blocked <=#Tp 1'b1;
end


endmodule

⌨️ 快捷键说明

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