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

📄 can_registers.v

📁 人民邮电出版社出版的《FPGA硬件接口设计实践》一书的代码
💻 V
📖 第 1 页 / 共 2 页
字号:
/* Bus Timing 1 register */
wire   [7:0] bus_timing_1;
can_register #(8) BUS_TIMING_1_REG
( .data_in(data_in),
  .data_out(bus_timing_1),
  .we(we_bus_timing_1),
  .clk(clk)
);

assign time_segment1 = bus_timing_1[3:0];
assign time_segment2 = bus_timing_1[6:4];
assign triple_sampling = bus_timing_1[7];
/* End Bus Timing 1 register */


/* Error Warning Limit register */
can_register_asyn #(8, 96) ERROR_WARNING_REG
( .data_in(data_in),
  .data_out(error_warning_limit),
  .we(we_error_warning_limit),
  .clk(clk),
  .rst(rst)
);
/* End Error Warning Limit register */



/* Clock Divider register */
wire   [7:0] clock_divider;
wire         clock_off;
wire   [2:0] cd;
reg    [2:0] clkout_div;
reg    [2:0] clkout_cnt;
reg          clkout_tmp;
//reg          clkout;

can_register #(1) CLOCK_DIVIDER_REG_7
( .data_in(data_in[7]),
  .data_out(clock_divider[7]),
  .we(we_clock_divider_hi),
  .clk(clk)
);

assign clock_divider[6:4] = 3'h0;

can_register #(1) CLOCK_DIVIDER_REG_3
( .data_in(data_in[3]),
  .data_out(clock_divider[3]),
  .we(we_clock_divider_hi),
  .clk(clk)
);

can_register #(3) CLOCK_DIVIDER_REG_LOW
( .data_in(data_in[2:0]),
  .data_out(clock_divider[2:0]),
  .we(we_clock_divider_low),
  .clk(clk)
);

assign extended_mode = clock_divider[7];
assign clock_off     = clock_divider[3];
assign cd[2:0]       = clock_divider[2:0];



always @ (cd)
begin
  case (cd)                       // synopsys_full_case synopsys_paralel_case
    3'b000 : clkout_div <= 0;
    3'b001 : clkout_div <= 1;
    3'b010 : clkout_div <= 2;
    3'b011 : clkout_div <= 3;
    3'b100 : clkout_div <= 4;
    3'b101 : clkout_div <= 5;
    3'b110 : clkout_div <= 6;
    3'b111 : clkout_div <= 0;
  endcase
end



always @ (posedge clk or posedge rst)
begin
  if (rst)
    clkout_cnt <= 3'h0;
  else if (clkout_cnt == clkout_div)
    clkout_cnt <=#Tp 3'h0;
  else
    clkout_cnt <= clkout_cnt + 1'b1;
end



always @ (posedge clk or posedge rst)
begin
  if (rst)
    clkout_tmp <= 1'b0;
  else if (clkout_cnt == clkout_div)
    clkout_tmp <=#Tp ~clkout_tmp;
end


/*
//always @ (cd or clk or clkout_tmp or clock_off)
always @ (cd or clkout_tmp or clock_off)
begin
  if (clock_off)
    clkout <=#Tp 1'b1;
//  else if (&cd)
//    clkout <=#Tp clk;
  else
    clkout <=#Tp clkout_tmp;
end
*/
assign clkout = clock_off ? 1'b1 : ((&cd)? clk : clkout_tmp);



/* End Clock Divider register */




/* This section is for BASIC and EXTENDED mode */

/* Acceptance code register */
can_register #(8) ACCEPTANCE_CODE_REG0
( .data_in(data_in),
  .data_out(acceptance_code_0),
  .we(we_acceptance_code_0),
  .clk(clk)
);
/* End: Acceptance code register */


/* Acceptance mask register */
can_register #(8) ACCEPTANCE_MASK_REG0
( .data_in(data_in),
  .data_out(acceptance_mask_0),
  .we(we_acceptance_mask_0),
  .clk(clk)
);
/* End: Acceptance mask register */
/* End: This section is for BASIC and EXTENDED mode */


/* Tx data 0 register. */
can_register #(8) TX_DATA_REG0
( .data_in(data_in),
  .data_out(tx_data_0),
  .we(we_tx_data_0),
  .clk(clk)
);
/* End: Tx data 0 register. */


/* Tx data 1 register. */
can_register #(8) TX_DATA_REG1
( .data_in(data_in),
  .data_out(tx_data_1),
  .we(we_tx_data_1),
  .clk(clk)
);
/* End: Tx data 1 register. */


/* Tx data 2 register. */
can_register #(8) TX_DATA_REG2
( .data_in(data_in),
  .data_out(tx_data_2),
  .we(we_tx_data_2),
  .clk(clk)
);
/* End: Tx data 2 register. */


/* Tx data 3 register. */
can_register #(8) TX_DATA_REG3
( .data_in(data_in),
  .data_out(tx_data_3),
  .we(we_tx_data_3),
  .clk(clk)
);
/* End: Tx data 3 register. */


/* Tx data 4 register. */
can_register #(8) TX_DATA_REG4
( .data_in(data_in),
  .data_out(tx_data_4),
  .we(we_tx_data_4),
  .clk(clk)
);
/* End: Tx data 4 register. */


/* Tx data 5 register. */
can_register #(8) TX_DATA_REG5
( .data_in(data_in),
  .data_out(tx_data_5),
  .we(we_tx_data_5),
  .clk(clk)
);
/* End: Tx data 5 register. */


/* Tx data 6 register. */
can_register #(8) TX_DATA_REG6
( .data_in(data_in),
  .data_out(tx_data_6),
  .we(we_tx_data_6),
  .clk(clk)
);
/* End: Tx data 6 register. */


/* Tx data 7 register. */
can_register #(8) TX_DATA_REG7
( .data_in(data_in),
  .data_out(tx_data_7),
  .we(we_tx_data_7),
  .clk(clk)
);
/* End: Tx data 7 register. */


/* Tx data 8 register. */
can_register #(8) TX_DATA_REG8
( .data_in(data_in),
  .data_out(tx_data_8),
  .we(we_tx_data_8),
  .clk(clk)
);
/* End: Tx data 8 register. */


/* Tx data 9 register. */
can_register #(8) TX_DATA_REG9
( .data_in(data_in),
  .data_out(tx_data_9),
  .we(we_tx_data_9),
  .clk(clk)
);
/* End: Tx data 9 register. */


/* Tx data 10 register. */
can_register #(8) TX_DATA_REG10
( .data_in(data_in),
  .data_out(tx_data_10),
  .we(we_tx_data_10),
  .clk(clk)
);
/* End: Tx data 10 register. */


/* Tx data 11 register. */
can_register #(8) TX_DATA_REG11
( .data_in(data_in),
  .data_out(tx_data_11),
  .we(we_tx_data_11),
  .clk(clk)
);
/* End: Tx data 11 register. */


/* Tx data 12 register. */
can_register #(8) TX_DATA_REG12
( .data_in(data_in),
  .data_out(tx_data_12),
  .we(we_tx_data_12),
  .clk(clk)
);
/* End: Tx data 12 register. */





/* This section is for EXTENDED mode */

/* Acceptance code register 1 */
can_register #(8) ACCEPTANCE_CODE_REG1
( .data_in(data_in),
  .data_out(acceptance_code_1),
  .we(we_acceptance_code_1),
  .clk(clk)
);
/* End: Acceptance code register */


/* Acceptance code register 2 */
can_register #(8) ACCEPTANCE_CODE_REG2
( .data_in(data_in),
  .data_out(acceptance_code_2),
  .we(we_acceptance_code_2),
  .clk(clk)
);
/* End: Acceptance code register */


/* Acceptance code register 3 */
can_register #(8) ACCEPTANCE_CODE_REG3
( .data_in(data_in),
  .data_out(acceptance_code_3),
  .we(we_acceptance_code_3),
  .clk(clk)
);
/* End: Acceptance code register */


/* Acceptance mask register 1 */
can_register #(8) ACCEPTANCE_MASK_REG1
( .data_in(data_in),
  .data_out(acceptance_mask_1),
  .we(we_acceptance_mask_1),
  .clk(clk)
);
/* End: Acceptance code register */


/* Acceptance mask register 2 */
can_register #(8) ACCEPTANCE_MASK_REG2
( .data_in(data_in),
  .data_out(acceptance_mask_2),
  .we(we_acceptance_mask_2),
  .clk(clk)
);
/* End: Acceptance code register */


/* Acceptance mask register 3 */
can_register #(8) ACCEPTANCE_MASK_REG3
( .data_in(data_in),
  .data_out(acceptance_mask_3),
  .we(we_acceptance_mask_3),
  .clk(clk)
);
/* End: Acceptance code register */


/* End: This section is for EXTENDED mode */




// Reading data from registers
always @ ( addr or read or extended_mode or mode or bus_timing_0 or bus_timing_1 or clock_divider or
           acceptance_code_0 or acceptance_code_1 or acceptance_code_2 or acceptance_code_3 or
           acceptance_mask_0 or acceptance_mask_1 or acceptance_mask_2 or acceptance_mask_3 or
           reset_mode or tx_data_0 or tx_data_1 or tx_data_2 or tx_data_3 or tx_data_4 or 
           tx_data_5 or tx_data_6 or tx_data_7 or tx_data_8 or tx_data_9 or status or 
           error_warning_limit or rx_err_cnt or tx_err_cnt or irq_en_ext or irq_reg or mode_ext or
           arbitration_lost_capture or rx_message_counter or mode_basic or error_capture_code
         )
begin
  if(read)  // read
    begin
      if (extended_mode)    // EXTENDED mode (Different register map depends on mode)
        begin
          case(addr)
            8'd0  :  data_out_tmp <= {4'b0000, mode_ext[3:1], mode[0]};
            8'd1  :  data_out_tmp <= 8'h0;
            8'd2  :  data_out_tmp <= status;
            8'd3  :  data_out_tmp <= irq_reg;
            8'd4  :  data_out_tmp <= irq_en_ext;
            8'd6  :  data_out_tmp <= bus_timing_0;
            8'd7  :  data_out_tmp <= bus_timing_1;
            8'd11 :  data_out_tmp <= {3'h0, arbitration_lost_capture[4:0]};
            8'd12 :  data_out_tmp <= error_capture_code;
            8'd13 :  data_out_tmp <= error_warning_limit;
            8'd14 :  data_out_tmp <= rx_err_cnt;
            8'd15 :  data_out_tmp <= tx_err_cnt;
            8'd16 :  data_out_tmp <= acceptance_code_0;
            8'd17 :  data_out_tmp <= acceptance_code_1;
            8'd18 :  data_out_tmp <= acceptance_code_2;
            8'd19 :  data_out_tmp <= acceptance_code_3;
            8'd20 :  data_out_tmp <= acceptance_mask_0;
            8'd21 :  data_out_tmp <= acceptance_mask_1;
            8'd22 :  data_out_tmp <= acceptance_mask_2;
            8'd23 :  data_out_tmp <= acceptance_mask_3;
            8'd24 :  data_out_tmp <= 8'h0;
            8'd25 :  data_out_tmp <= 8'h0;
            8'd26 :  data_out_tmp <= 8'h0;
            8'd27 :  data_out_tmp <= 8'h0;
            8'd28 :  data_out_tmp <= 8'h0;
            8'd29 :  data_out_tmp <= {1'b0, rx_message_counter};
            8'd31 :  data_out_tmp <= clock_divider;
    
            default: data_out_tmp <= 8'h0;
          endcase
        end
      else                  // BASIC mode
        begin
          case(addr)
            8'd0  :  data_out_tmp <= {3'b001, mode_basic[4:1], mode[0]};
            8'd1  :  data_out_tmp <= 8'hff;
            8'd2  :  data_out_tmp <= status;
            8'd3  :  data_out_tmp <= {4'hf, irq_reg[3:0]};
            8'd4  :  data_out_tmp <= reset_mode? acceptance_code_0 : 8'hff;
            8'd5  :  data_out_tmp <= reset_mode? acceptance_mask_0 : 8'hff;
            8'd6  :  data_out_tmp <= reset_mode? bus_timing_0 : 8'hff;
            8'd7  :  data_out_tmp <= reset_mode? bus_timing_1 : 8'hff;
            8'd10 :  data_out_tmp <= reset_mode? 8'hff : tx_data_0;
            8'd11 :  data_out_tmp <= reset_mode? 8'hff : tx_data_1;
            8'd12 :  data_out_tmp <= reset_mode? 8'hff : tx_data_2;
            8'd13 :  data_out_tmp <= reset_mode? 8'hff : tx_data_3;
            8'd14 :  data_out_tmp <= reset_mode? 8'hff : tx_data_4;
            8'd15 :  data_out_tmp <= reset_mode? 8'hff : tx_data_5;
            8'd16 :  data_out_tmp <= reset_mode? 8'hff : tx_data_6;
            8'd17 :  data_out_tmp <= reset_mode? 8'hff : tx_data_7;
            8'd18 :  data_out_tmp <= reset_mode? 8'hff : tx_data_8;
            8'd19 :  data_out_tmp <= reset_mode? 8'hff : tx_data_9;
            8'd31 :  data_out_tmp <= clock_divider;
    
            default: data_out_tmp <= 8'h0;
          endcase
        end
    end
  else
    data_out_tmp <= 8'h0;
end


always @ (posedge clk or posedge rst)
begin
  if (rst)
    data_out <= 0;
  else if (read)
    data_out <=#Tp data_out_tmp;
end

// Some interrupts exist in basic mode and in extended mode. Since they are in different registers they need to be multiplexed.
assign data_overrun_irq_en  = extended_mode ? data_overrun_irq_en_ext  : overrun_irq_en_basic;
assign error_warning_irq_en = extended_mode ? error_warning_irq_en_ext : error_irq_en_basic;
assign transmit_irq_en      = extended_mode ? transmit_irq_en_ext      : transmit_irq_en_basic;
assign receive_irq_en       = extended_mode ? receive_irq_en_ext       : receive_irq_en_basic;


reg data_overrun_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    data_overrun_irq <= 1'b0;
  else if (overrun & (~overrun_q) & data_overrun_irq_en)
    data_overrun_irq <=#Tp 1'b1;
  else if (read_irq_reg)
    data_overrun_irq <=#Tp 1'b0;
end


reg transmit_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    transmit_irq <= 1'b0;
  else if (transmit_buffer_status & (~transmit_buffer_status_q) & transmit_irq_en)
    transmit_irq <=#Tp 1'b1;
  else if (read_irq_reg)
    transmit_irq <=#Tp 1'b0;
end


reg receive_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    receive_irq <= 1'b0;
  else if (release_buffer)
    receive_irq <=#Tp 1'b0;
  else if ((~info_empty) & (~receive_irq) & receive_irq_en)
    receive_irq <=#Tp 1'b1;
end


reg error_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_irq <= 1'b0;
  else if (((error_status ^ error_status_q) | (node_bus_off ^ node_bus_off_q)) & error_warning_irq_en)
    error_irq <=#Tp 1'b1;
  else if (read_irq_reg)
    error_irq <=#Tp 1'b0;
end


reg bus_error_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    bus_error_irq <= 1'b0;
  else if (set_bus_error_irq & bus_error_irq_en)
    bus_error_irq <=#Tp 1'b1;
  else if (read_irq_reg)
    bus_error_irq <=#Tp 1'b0;
end


reg arbitration_lost_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    arbitration_lost_irq <= 1'b0;
  else if (set_arbitration_lost_irq & arbitration_lost_irq_en)
    arbitration_lost_irq <=#Tp 1'b1;
  else if (read_irq_reg)
    arbitration_lost_irq <=#Tp 1'b0;
end



reg error_passive_irq;
always @ (posedge clk or posedge rst)
begin
  if (rst)
    error_passive_irq <= 1'b0;
  else if ((node_error_passive & (~node_error_passive_q) | (~node_error_passive) & node_error_passive_q & node_error_active) & error_passive_irq_en)
    error_passive_irq <=#Tp 1'b1;
  else if (read_irq_reg)
    error_passive_irq <=#Tp 1'b0;
end



assign irq_reg = {bus_error_irq, arbitration_lost_irq, error_passive_irq, 1'b0, data_overrun_irq, error_irq, transmit_irq, receive_irq};

assign irq = data_overrun_irq | transmit_irq | receive_irq | error_irq | bus_error_irq | arbitration_lost_irq | error_passive_irq;





endmodule

⌨️ 快捷键说明

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