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

📄 spi_shift.v

📁 串行数据SPI master的开源控制器
💻 V
字号:
//////////////////////////////////////////////////////////////////////////                                                              ////////  spi_shift.v                                                 ////////                                                              ////////  This file is part of the SPI IP core project                ////////  http://www.opencores.org/projects/spi/                      ////////                                                              ////////  Author(s):                                                  ////////      - Simon Srot (simons@opencores.org)                     ////////                                                              ////////  All additional information is avaliable in the Readme.txt   ////////  file.                                                       ////////                                                              //////////////////////////////////////////////////////////////////////////////                                                              //////// Copyright (C) 2002 Authors                                   ////////                                                              //////// This source file may be used and distributed without         //////// restriction provided that this copyright statement is not    //////// removed from the file and that any derivative work contains  //////// the original copyright notice and the associated disclaimer. ////////                                                              //////// This source file is free software; you can redistribute it   //////// and/or modify it under the terms of the GNU Lesser General   //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any   //////// later version.                                               ////////                                                              //////// This source is distributed in the hope that it will be       //////// useful, but WITHOUT ANY WARRANTY; without even the implied   //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //////// PURPOSE.  See the GNU Lesser General Public License for more //////// details.                                                     ////////                                                              //////// You should have received a copy of the GNU Lesser General    //////// Public License along with this source; if not, download it   //////// from http://www.opencores.org/lgpl.shtml                     ////////                                                              //////////////////////////////////////////////////////////////////////////`include "spi_defines.v"`include "timescale.v"module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,                  pos_edge, neg_edge, rx_negedge, tx_negedge,                  tip, last,                   p_in, p_out, s_clk, s_in, s_out);  parameter Tp = 1;    input                          clk;          // system clock  input                          rst;          // reset  input                    [3:0] latch;        // latch signal for storing the data in shift register  input                    [3:0] byte_sel;     // byte select signals for storing the data in shift register  input [`SPI_CHAR_LEN_BITS-1:0] len;          // data len in bits (minus one)  input                          lsb;          // lbs first on the line  input                          go;           // start stansfer  input                          pos_edge;     // recognize posedge of sclk  input                          neg_edge;     // recognize negedge of sclk  input                          rx_negedge;   // s_in is sampled on negative edge   input                          tx_negedge;   // s_out is driven on negative edge  output                         tip;          // transfer in progress  output                         last;         // last bit  input                   [31:0] p_in;         // parallel in  output     [`SPI_MAX_CHAR-1:0] p_out;        // parallel out  input                          s_clk;        // serial clock  input                          s_in;         // serial in  output                         s_out;        // serial out                                                 reg                            s_out;          reg                            tip;                                reg     [`SPI_CHAR_LEN_BITS:0] cnt;          // data bit count  reg        [`SPI_MAX_CHAR-1:0] data;         // shift register  wire    [`SPI_CHAR_LEN_BITS:0] tx_bit_pos;   // next bit position  wire    [`SPI_CHAR_LEN_BITS:0] rx_bit_pos;   // next bit position  wire                           rx_clk;       // rx clock enable  wire                           tx_clk;       // tx clock enable    assign p_out = data;    assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};  assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :                             (rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});    assign last = !(|cnt);    assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);  assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;    // Character bit counter  always @(posedge clk or posedge rst)  begin    if(rst)      cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};    else      begin        if(tip)          cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;        else          cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};      end  end    // Transfer in progress  always @(posedge clk or posedge rst)  begin    if(rst)      tip <= #Tp 1'b0;  else if(go && ~tip)    tip <= #Tp 1'b1;  else if(tip && last && pos_edge)    tip <= #Tp 1'b0;  end    // Sending bits to the line  always @(posedge clk or posedge rst)  begin    if (rst)      s_out   <= #Tp 1'b0;    else      s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;  end    // Receiving bits from the line  always @(posedge clk or posedge rst)  begin    if (rst)      data   <= #Tp {`SPI_MAX_CHAR{1'b0}};`ifdef SPI_MAX_CHAR_128    else if (latch[0] && !tip)      begin        if (byte_sel[3])          data[31:24] <= #Tp p_in[31:24];        if (byte_sel[2])          data[23:16] <= #Tp p_in[23:16];        if (byte_sel[1])          data[15:8] <= #Tp p_in[15:8];        if (byte_sel[0])          data[7:0] <= #Tp p_in[7:0];      end    else if (latch[1] && !tip)      begin        if (byte_sel[3])          data[63:56] <= #Tp p_in[31:24];        if (byte_sel[2])          data[55:48] <= #Tp p_in[23:16];        if (byte_sel[1])          data[47:40] <= #Tp p_in[15:8];        if (byte_sel[0])          data[39:32] <= #Tp p_in[7:0];      end    else if (latch[2] && !tip)      begin        if (byte_sel[3])          data[95:88] <= #Tp p_in[31:24];        if (byte_sel[2])          data[87:80] <= #Tp p_in[23:16];        if (byte_sel[1])          data[79:72] <= #Tp p_in[15:8];        if (byte_sel[0])          data[71:64] <= #Tp p_in[7:0];      end    else if (latch[3] && !tip)      begin        if (byte_sel[3])          data[127:120] <= #Tp p_in[31:24];        if (byte_sel[2])          data[119:112] <= #Tp p_in[23:16];        if (byte_sel[1])          data[111:104] <= #Tp p_in[15:8];        if (byte_sel[0])          data[103:96] <= #Tp p_in[7:0];      end`else`ifdef SPI_MAX_CHAR_64    else if (latch[0] && !tip)      begin        if (byte_sel[3])          data[31:24] <= #Tp p_in[31:24];        if (byte_sel[2])          data[23:16] <= #Tp p_in[23:16];        if (byte_sel[1])          data[15:8] <= #Tp p_in[15:8];        if (byte_sel[0])          data[7:0] <= #Tp p_in[7:0];      end    else if (latch[1] && !tip)      begin        if (byte_sel[3])          data[63:56] <= #Tp p_in[31:24];        if (byte_sel[2])          data[55:48] <= #Tp p_in[23:16];        if (byte_sel[1])          data[47:40] <= #Tp p_in[15:8];        if (byte_sel[0])          data[39:32] <= #Tp p_in[7:0];      end`else    else if (latch[0] && !tip)      begin      `ifdef SPI_MAX_CHAR_8        if (byte_sel[0])          data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];      `endif      `ifdef SPI_MAX_CHAR_16        if (byte_sel[0])          data[7:0] <= #Tp p_in[7:0];        if (byte_sel[1])          data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];      `endif      `ifdef SPI_MAX_CHAR_24        if (byte_sel[0])          data[7:0] <= #Tp p_in[7:0];        if (byte_sel[1])          data[15:8] <= #Tp p_in[15:8];        if (byte_sel[2])          data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];      `endif      `ifdef SPI_MAX_CHAR_32        if (byte_sel[0])          data[7:0] <= #Tp p_in[7:0];        if (byte_sel[1])          data[15:8] <= #Tp p_in[15:8];        if (byte_sel[2])          data[23:16] <= #Tp p_in[23:16];        if (byte_sel[3])          data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];      `endif      end`endif`endif    else      data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];  end  endmodule

⌨️ 快捷键说明

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