qjfun

基于FPGA的SPI串口之二

0
阅读(1767)


SPI的另一个Verilog程序,

此设计,加入fifo用以缓存发送或接收数据,

同时,master与slave的transfer register通过mosi和miso相连,

形成环路,

此设计更符合SPI协议


    wfempty    -->    发送fifo空信号bit

    wfdout      -->    fifo输出q

    clkcnt        -->    clk分频,累减,为0时输出。

    rfwe         -->    将接收的数据存入接收fifo

    bcnt         -->    发送bit计数



  // generate clock enable signal
  wire ena = ~|clkcnt;

  // transfer statemachine
  always @(posedge clk_i)
    if (~spe)
      begin
          state <= #1 2'b00; // idle
          bcnt  <= #1 3'h0;
          treg  <= #1 8'h00;
          wfre  <= #1 1'b0;
          rfwe  <= #1 1'b0;
          sck_o <= #1 1'b0;
      end
    else
      begin
         wfre <= #1 1'b0;
         rfwe <= #1 1'b0;

         case (state) //synopsys full_case parallel_case
           2'b00: // idle state
              begin
                  bcnt  <= #1 3'h7;   // set transfer counter
                  treg  <= #1 wfdout; // load transfer register
                  sck_o <= #1 cpol;   // set sck
                  ss_n <= #1 1'b1;

                  if (~wfempty) begin
                    wfre  <= #1 1'b1;
                    state <= #1 2'b01;
                    ss_n  <= #1 1'b0;
                    if (cpha) sck_o <= #1 ~sck_o;
                  end
              end

           2'b01: // clock-phase2, next data
              if (ena) begin
                sck_o   <= #1 ~sck_o;
                state   <= #1 2'b11;
              end

           2'b11: // clock phase1
              if (ena) begin
                treg <= #1 {treg[6:0], miso};
                bcnt <= #1 bcnt -3'h1;

                if (~|bcnt) begin
                  state <= #1 2'b00;
                  sck_o <= #1 cpol;
                  rfwe  <= #1 1'b1;
                  ss_n <= #1 1'b1;
                end else begin
                  state <= #1 2'b01;
                  sck_o <= #1 ~sck_o;
                end
              end

           2'b10: state <= #1 2'b00;
         endcase
      end

  assign mosi = treg[7];