[Verilog HDL] SPI总线的verilog实现

[复制链接]
 楼主| gaochy1126 发表于 2023-1-31 21:46 | 显示全部楼层 |阅读模式
  1. module spi_module
  2. (
  3.     input               I_clk       , // 全局时钟50MHz
  4.     input               I_rst_n     , // 复位信号,低电平有效
  5.     input               I_rx_en     , // 读使能信号
  6.     input               I_tx_en     , // 发送使能信号
  7.     input        [7:0]  I_data_in   , // 要发送的数据
  8.     output  reg  [7:0]  O_data_out  , // 接收到的数据
  9.     output  reg         O_tx_done   , // 发送一个字节完毕标志位
  10.     output  reg         O_rx_done   , // 接收一个字节完毕标志位
  11.    
  12.     // 四线标准SPI信号定义
  13.     input               I_spi_miso  , // SPI串行输入,用来接收从机的数据
  14.     output  reg         O_spi_sck   , // SPI时钟
  15.     output  reg         O_spi_cs    , // SPI片选信号
  16.     output  reg         O_spi_mosi    // SPI输出,用来给从机发送数据         
  17. );

  18. reg [3:0]   R_tx_state      ;
  19. reg [3:0]   R_rx_state      ;

  20. always @(posedge I_clk or negedge I_rst_n)
  21. begin
  22.     if(!I_rst_n)
  23.         begin
  24.             R_tx_state  <=  4'd0    ;
  25.             R_rx_state  <=  4'd0    ;
  26.             O_spi_cs    <=  1'b1    ;
  27.             O_spi_sck   <=  1'b0    ;
  28.             O_spi_mosi  <=  1'b0    ;
  29.             O_tx_done   <=  1'b0    ;
  30.             O_rx_done   <=  1'b0    ;
  31.             O_data_out  <=  8'd0    ;
  32.         end
  33.     else if(I_tx_en) // 发送使能信号打开的情况下
  34.         begin
  35.             O_spi_cs    <=  1'b0    ; // 把片选CS拉低
  36.             case(R_tx_state)
  37.                 4'd1, 4'd3 , 4'd5 , 4'd7  ,
  38.                 4'd9, 4'd11, 4'd13, 4'd15 : //整合奇数状态
  39.                     begin
  40.                         O_spi_sck   <=  1'b1                ;
  41.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  42.                         O_tx_done   <=  1'b0                ;
  43.                     end
  44.                 4'd0:    // 发送第7位
  45.                     begin
  46.                         O_spi_mosi  <=  I_data_in[7]        ;
  47.                         O_spi_sck   <=  1'b0                ;
  48.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  49.                         O_tx_done   <=  1'b0                ;
  50.                     end
  51.                 4'd2:    // 发送第6位
  52.                     begin
  53.                         O_spi_mosi  <=  I_data_in[6]        ;
  54.                         O_spi_sck   <=  1'b0                ;
  55.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  56.                         O_tx_done   <=  1'b0                ;
  57.                     end
  58.                 4'd4:    // 发送第5位
  59.                     begin
  60.                         O_spi_mosi  <=  I_data_in[5]        ;
  61.                         O_spi_sck   <=  1'b0                ;
  62.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  63.                         O_tx_done   <=  1'b0                ;
  64.                     end
  65.                 4'd6:    // 发送第4位
  66.                     begin
  67.                         O_spi_mosi  <=  I_data_in[4]        ;
  68.                         O_spi_sck   <=  1'b0                ;
  69.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  70.                         O_tx_done   <=  1'b0                ;
  71.                     end
  72.                 4'd8:    // 发送第3位
  73.                     begin
  74.                         O_spi_mosi  <=  I_data_in[3]        ;
  75.                         O_spi_sck   <=  1'b0                ;
  76.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  77.                         O_tx_done   <=  1'b0                ;
  78.                     end                           
  79.                 4'd10:    // 发送第2位
  80.                     begin
  81.                         O_spi_mosi  <=  I_data_in[2]        ;
  82.                         O_spi_sck   <=  1'b0                ;
  83.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  84.                         O_tx_done   <=  1'b0                ;
  85.                     end
  86.                 4'd12:    // 发送第1位
  87.                     begin
  88.                         O_spi_mosi  <=  I_data_in[1]        ;
  89.                         O_spi_sck   <=  1'b0                ;
  90.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  91.                         O_tx_done   <=  1'b0                ;
  92.                     end
  93.                 4'd14:    // 发送第0位
  94.                     begin
  95.                         O_spi_mosi  <=  I_data_in[0]        ;
  96.                         O_spi_sck   <=  1'b0                ;
  97.                         R_tx_state  <=  R_tx_state + 1'b1   ;
  98.                         O_tx_done   <=  1'b1                ;
  99.                     end
  100.                 default:R_tx_state  <=  4'd0                ;   
  101.             endcase
  102.         end
  103.     else if(I_rx_en) // 接收使能信号打开的情况下
  104.         begin
  105.             O_spi_cs    <=  1'b0        ; // 拉低片选信号CS
  106.             case(R_rx_state)
  107.                 4'd0, 4'd2 , 4'd4 , 4'd6  ,
  108.                 4'd8, 4'd10, 4'd12, 4'd14 : //整合偶数状态
  109.                     begin
  110.                         O_spi_sck      <=  1'b0                ;
  111.                         R_rx_state     <=  R_rx_state + 1'b1   ;
  112.                         O_rx_done      <=  1'b0                ;
  113.                     end
  114.                 4'd1:    // 接收第7位
  115.                     begin                       
  116.                         O_spi_sck       <=  1'b1                ;
  117.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  118.                         O_rx_done       <=  1'b0                ;
  119.                         O_data_out[7]   <=  I_spi_miso          ;   
  120.                     end
  121.                 4'd3:    // 接收第6位
  122.                     begin
  123.                         O_spi_sck       <=  1'b1                ;
  124.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  125.                         O_rx_done       <=  1'b0                ;
  126.                         O_data_out[6]   <=  I_spi_miso          ;
  127.                     end
  128.                 4'd5:    // 接收第5位
  129.                     begin
  130.                         O_spi_sck       <=  1'b1                ;
  131.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  132.                         O_rx_done       <=  1'b0                ;
  133.                         O_data_out[5]   <=  I_spi_miso          ;
  134.                     end
  135.                 4'd7:    // 接收第4位
  136.                     begin
  137.                         O_spi_sck       <=  1'b1                ;
  138.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  139.                         O_rx_done       <=  1'b0                ;
  140.                         O_data_out[4]   <=  I_spi_miso          ;
  141.                     end
  142.                 4'd9:    // 接收第3位
  143.                     begin
  144.                         O_spi_sck       <=  1'b1                ;
  145.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  146.                         O_rx_done       <=  1'b0                ;
  147.                         O_data_out[3]   <=  I_spi_miso          ;
  148.                     end                           
  149.                 4'd11:    // 接收第2位
  150.                     begin
  151.                         O_spi_sck       <=  1'b1                ;
  152.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  153.                         O_rx_done       <=  1'b0                ;
  154.                         O_data_out[2]   <=  I_spi_miso          ;
  155.                     end
  156.                 4'd13:    // 接收第1位
  157.                     begin
  158.                         O_spi_sck       <=  1'b1                ;
  159.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  160.                         O_rx_done       <=  1'b0                ;
  161.                         O_data_out[1]   <=  I_spi_miso          ;
  162.                     end
  163.                 4'd15:    // 接收第0位
  164.                     begin
  165.                         O_spi_sck       <=  1'b1                ;
  166.                         R_rx_state      <=  R_rx_state + 1'b1   ;
  167.                         O_rx_done       <=  1'b1                ;
  168.                         O_data_out[0]   <=  I_spi_miso          ;
  169.                     end
  170.                 default:R_rx_state  <=  4'd0                    ;   
  171.             endcase
  172.         end   
  173.     else
  174.         begin
  175.             R_tx_state  <=  4'd0    ;
  176.             R_rx_state  <=  4'd0    ;
  177.             O_tx_done   <=  1'b0    ;
  178.             O_rx_done   <=  1'b0    ;
  179.             O_spi_cs    <=  1'b1    ;
  180.             O_spi_sck   <=  1'b0    ;
  181.             O_spi_mosi  <=  1'b0    ;
  182.             O_data_out  <=  8'd0    ;
  183.         end      
  184. end

  185. endmodule


您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1148

主题

11651

帖子

26

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1148

主题

11651

帖子

26

粉丝
快速回复 在线客服 返回列表 返回顶部