1 | ////////////////////////////////////////////////////////////////////// |
---|
2 | //// //// |
---|
3 | //// spi_shift.v //// |
---|
4 | //// //// |
---|
5 | //// This file is part of the SPI IP core project //// |
---|
6 | //// http://www.opencores.org/projects/spi/ //// |
---|
7 | //// //// |
---|
8 | //// Author(s): //// |
---|
9 | //// - Simon Srot (simons@opencores.org) //// |
---|
10 | //// //// |
---|
11 | //// All additional information is avaliable in the Readme.txt //// |
---|
12 | //// file. //// |
---|
13 | //// //// |
---|
14 | ////////////////////////////////////////////////////////////////////// |
---|
15 | //// //// |
---|
16 | //// Copyright (C) 2002 Authors //// |
---|
17 | //// //// |
---|
18 | //// This source file may be used and distributed without //// |
---|
19 | //// restriction provided that this copyright statement is not //// |
---|
20 | //// removed from the file and that any derivative work contains //// |
---|
21 | //// the original copyright notice and the associated disclaimer. //// |
---|
22 | //// //// |
---|
23 | //// This source file is free software; you can redistribute it //// |
---|
24 | //// and/or modify it under the terms of the GNU Lesser General //// |
---|
25 | //// Public License as published by the Free Software Foundation; //// |
---|
26 | //// either version 2.1 of the License, or (at your option) any //// |
---|
27 | //// later version. //// |
---|
28 | //// //// |
---|
29 | //// This source is distributed in the hope that it will be //// |
---|
30 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
---|
31 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
---|
32 | //// PURPOSE. See the GNU Lesser General Public License for more //// |
---|
33 | //// details. //// |
---|
34 | //// //// |
---|
35 | //// You should have received a copy of the GNU Lesser General //// |
---|
36 | //// Public License along with this source; if not, download it //// |
---|
37 | //// from http://www.opencores.org/lgpl.shtml //// |
---|
38 | //// //// |
---|
39 | ////////////////////////////////////////////////////////////////////// |
---|
40 | //// |
---|
41 | //// /* Modifications to spi_shift.v */ |
---|
42 | //// /* Copyright (c) 2006 Rice University */ |
---|
43 | //// /* All Rights Reserved */ |
---|
44 | //// /* This code is covered by the Rice-WARP license */ |
---|
45 | //// /* See http://warp.rice.edu/license/ for details */ |
---|
46 | |
---|
47 | |
---|
48 | module spi_shift (clk, rst, len, lsb, go, |
---|
49 | pos_edge, neg_edge, rx_negedge, tx_negedge, |
---|
50 | tip, last, |
---|
51 | p_in, p_out, s_clk, s_out); |
---|
52 | |
---|
53 | parameter Tp = 1; |
---|
54 | |
---|
55 | input clk; // system clock |
---|
56 | input rst; // reset |
---|
57 | input [4:0] len; // data len in bits (minus one) |
---|
58 | input lsb; // lbs first on the line |
---|
59 | input go; // start stansfer |
---|
60 | input pos_edge; // recognize posedge of sclk |
---|
61 | input neg_edge; // recognize negedge of sclk |
---|
62 | input rx_negedge; // s_in is sampled on negative edge |
---|
63 | input tx_negedge; // s_out is driven on negative edge |
---|
64 | output tip; // transfer in progress |
---|
65 | output last; // last bit |
---|
66 | input /*31*/ [17:0] p_in; // parallel in |
---|
67 | output [17:0] p_out; // parallel out |
---|
68 | input s_clk; // serial clock |
---|
69 | output s_out; // serial out |
---|
70 | |
---|
71 | reg s_out; |
---|
72 | reg tip; |
---|
73 | |
---|
74 | reg [5:0] cnt; // data bit count |
---|
75 | wire [17:0] data; // shift register |
---|
76 | wire [5:0] tx_bit_pos; // next bit position |
---|
77 | wire [5:0] rx_bit_pos; // next bit position |
---|
78 | wire rx_clk; // rx clock enable |
---|
79 | wire tx_clk; // tx clock enable |
---|
80 | |
---|
81 | //assign p_out = data; |
---|
82 | assign data = p_in; |
---|
83 | |
---|
84 | assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{5{1'b0}},1'b1}; |
---|
85 | assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{5{1'b0}},1'b1} : cnt) : |
---|
86 | (rx_negedge ? cnt : cnt - {{5{1'b0}},1'b1}); |
---|
87 | |
---|
88 | assign last = !(|cnt); |
---|
89 | |
---|
90 | assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk); |
---|
91 | assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last; |
---|
92 | |
---|
93 | // Character bit counter |
---|
94 | always @(posedge clk or posedge rst) |
---|
95 | begin |
---|
96 | if(rst) |
---|
97 | cnt <= #Tp {6{1'b0}}; |
---|
98 | else |
---|
99 | begin |
---|
100 | if(tip) |
---|
101 | cnt <= #Tp pos_edge ? (cnt - {{5{1'b0}}, 1'b1}) : cnt; |
---|
102 | else |
---|
103 | cnt <= #Tp !(|len) ? {1'b1, {5{1'b0}}} : {1'b0, len}; |
---|
104 | end |
---|
105 | end |
---|
106 | |
---|
107 | // Transfer in progress |
---|
108 | always @(posedge clk or posedge rst) |
---|
109 | begin |
---|
110 | if(rst) |
---|
111 | tip <= #Tp 1'b0; |
---|
112 | else if(go && ~tip) |
---|
113 | tip <= #Tp 1'b1; |
---|
114 | else if(tip && last && pos_edge) |
---|
115 | tip <= #Tp 1'b0; |
---|
116 | end |
---|
117 | |
---|
118 | // Sending bits to the line |
---|
119 | always @(posedge clk or posedge rst) |
---|
120 | begin |
---|
121 | if (rst) |
---|
122 | s_out <= #Tp 1'b0; |
---|
123 | else |
---|
124 | s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[4:0]] : s_out; |
---|
125 | end |
---|
126 | |
---|
127 | |
---|
128 | endmodule |
---|
129 | |
---|