@@ -42,16 +42,18 @@ entity SPI_MASTER is
42
42
CLK : in std_logic ; -- system clock
43
43
RST : in std_logic ; -- high active synchronous reset
44
44
-- SPI MASTER INTERFACE
45
- SCLK : out std_logic ;
46
- CS_N : out std_logic_vector (SLAVE_COUNT- 1 downto 0 );
47
- MOSI : out std_logic ;
48
- MISO : in std_logic ;
49
- -- USER INTERFACE
50
- ADDR : in std_logic_vector (integer (ceil (log2 (real (SLAVE_COUNT))))- 1 downto 0 ); -- slave address
51
- READY : out std_logic ; -- when READY = 1, SPI master is ready to accept input data
52
- DIN : in std_logic_vector (7 downto 0 ); -- input data for slave
53
- DIN_VLD : in std_logic ; -- when DIN_VLD = 1, input data are valid and can be accept
54
- DOUT : out std_logic_vector (7 downto 0 ); -- output data from slave
45
+ SCLK : out std_logic ; -- SPI clock
46
+ CS_N : out std_logic_vector (SLAVE_COUNT- 1 downto 0 ); -- SPI chip select, active in low
47
+ MOSI : out std_logic ; -- SPI serial data from master to slave
48
+ MISO : in std_logic ; -- SPI serial data from slave to master
49
+ -- INPUT USER INTERFACE
50
+ ADDR : in std_logic_vector (integer (ceil (log2 (real (SLAVE_COUNT))))- 1 downto 0 ); -- SPI slave address
51
+ DIN : in std_logic_vector (7 downto 0 ); -- input data for SPI slave
52
+ DIN_LAST : in std_logic ; -- when DIN_LAST = 1, after transmit these input data is asserted CS_N
53
+ DIN_VLD : in std_logic ; -- when DIN_VLD = 1, input data are valid
54
+ READY : out std_logic ; -- when READY = 1, valid input data are accept
55
+ -- OUTPUT USER INTERFACE
56
+ DOUT : out std_logic_vector (7 downto 0 ); -- output data from SPI slave
55
57
DOUT_VLD : out std_logic -- when DOUT_VLD = 1, output data are valid
56
58
);
57
59
end SPI_MASTER ;
@@ -68,6 +70,7 @@ architecture RTL of SPI_MASTER is
68
70
signal sys_clk_cnt_rst : std_logic ;
69
71
signal spi_clk : std_logic ;
70
72
signal spi_clk_en : std_logic ;
73
+ signal din_last_reg_n : std_logic ;
71
74
signal first_edge_en : std_logic ;
72
75
signal second_edge_en : std_logic ;
73
76
signal chip_select_n : std_logic ;
@@ -80,7 +83,7 @@ architecture RTL of SPI_MASTER is
80
83
signal rx_data_vld : std_logic ;
81
84
signal master_ready : std_logic ;
82
85
83
- type state is (idle, first_edge, second_edge, transmit_end, disable_cs );
86
+ type state is (idle, first_edge, second_edge, transmit_end, transmit_gap );
84
87
signal present_state, next_state : state;
85
88
86
89
begin
89
92
90
93
load_data <= master_ready and DIN_VLD;
91
94
READY <= master_ready;
92
- DOUT <= shreg;
93
- DOUT_VLD <= rx_data_vld;
94
-
95
+
95
96
-- -------------------------------------------------------------------------
96
97
-- SYSTEM CLOCK COUNTER
97
98
-- -------------------------------------------------------------------------
@@ -127,6 +128,24 @@ begin
127
128
128
129
SCLK <= spi_clk;
129
130
131
+ -- -------------------------------------------------------------------------
132
+ -- BIT COUNTER
133
+ -- -------------------------------------------------------------------------
134
+
135
+ bit_cnt_max <= '1' when (bit_cnt = "111" ) else '0' ;
136
+ bit_cnt_rst <= RST or not spi_clk_en;
137
+
138
+ bit_cnt_p : process (CLK)
139
+ begin
140
+ if (rising_edge (CLK)) then
141
+ if (bit_cnt_rst = '1' ) then
142
+ bit_cnt <= (others => '0' );
143
+ elsif (second_edge_en = '1' ) then
144
+ bit_cnt <= bit_cnt + 1 ;
145
+ end if ;
146
+ end if ;
147
+ end process ;
148
+
130
149
-- -------------------------------------------------------------------------
131
150
-- SPI MASTER ADDRESSING
132
151
-- -------------------------------------------------------------------------
@@ -153,6 +172,21 @@ begin
153
172
end process ;
154
173
end generate ;
155
174
175
+ -- -------------------------------------------------------------------------
176
+ -- DIN LAST RESISTER
177
+ -- -------------------------------------------------------------------------
178
+
179
+ din_last_reg_n_p : process (CLK)
180
+ begin
181
+ if (rising_edge (CLK)) then
182
+ if (RST = '1' ) then
183
+ din_last_reg_n <= '0' ;
184
+ elsif (load_data = '1' ) then
185
+ din_last_reg_n <= not DIN_LAST;
186
+ end if ;
187
+ end if ;
188
+ end process ;
189
+
156
190
-- -------------------------------------------------------------------------
157
191
-- MISO SAMPLE REGISTER
158
192
-- -------------------------------------------------------------------------
@@ -181,22 +215,20 @@ begin
181
215
end if ;
182
216
end process ;
183
217
218
+ DOUT <= shreg;
184
219
MOSI <= shreg(7 );
185
-
220
+
186
221
-- -------------------------------------------------------------------------
187
- -- BIT COUNTER
222
+ -- DATA OUT VALID RESISTER
188
223
-- -------------------------------------------------------------------------
189
224
190
- bit_cnt_max <= '1' when (bit_cnt = "111" ) else '0' ;
191
- bit_cnt_rst <= RST or not spi_clk_en;
192
-
193
- bit_cnt_p : process (CLK)
225
+ dout_vld_reg_p : process (CLK)
194
226
begin
195
227
if (rising_edge (CLK)) then
196
- if (bit_cnt_rst = '1' ) then
197
- bit_cnt <= ( others => '0' ) ;
198
- elsif (second_edge_en = '1' ) then
199
- bit_cnt <= bit_cnt + 1 ;
228
+ if (RST = '1' ) then
229
+ DOUT_VLD <= '0' ;
230
+ else
231
+ DOUT_VLD <= rx_data_vld ;
200
232
end if ;
201
233
end if ;
202
234
end process ;
@@ -221,9 +253,7 @@ begin
221
253
fsm_next_state_p : process (present_state, DIN_VLD, sys_clk_cnt_max,
222
254
bit_cnt_max)
223
255
begin
224
-
225
256
case present_state is
226
-
227
257
when idle =>
228
258
if (DIN_VLD = '1' ) then
229
259
next_state <= first_edge;
@@ -239,43 +269,42 @@ begin
239
269
end if ;
240
270
241
271
when second_edge =>
242
- if (sys_clk_cnt_max = '1' and bit_cnt_max = '0' ) then
243
- next_state <= first_edge;
244
- elsif (sys_clk_cnt_max = '1' and bit_cnt_max = '1' ) then
245
- next_state <= transmit_end;
272
+ if (sys_clk_cnt_max = '1' ) then
273
+ if (bit_cnt_max = '1' ) then
274
+ next_state <= transmit_end;
275
+ else
276
+ next_state <= first_edge;
277
+ end if ;
246
278
else
247
279
next_state <= second_edge;
248
280
end if ;
249
281
250
282
when transmit_end =>
251
- if (DIN_VLD = '1' ) then
252
- next_state <= first_edge ;
283
+ if (sys_clk_cnt_max = '1' ) then
284
+ next_state <= transmit_gap ;
253
285
else
254
- next_state <= disable_cs ;
286
+ next_state <= transmit_end ;
255
287
end if ;
256
288
257
- when disable_cs =>
289
+ when transmit_gap =>
258
290
if (sys_clk_cnt_max = '1' ) then
259
291
next_state <= idle;
260
292
else
261
- next_state <= disable_cs ;
293
+ next_state <= transmit_gap ;
262
294
end if ;
263
295
264
296
when others =>
265
297
next_state <= idle;
266
-
267
298
end case ;
268
299
end process ;
269
300
270
301
-- OUTPUTS LOGIC
271
- fsm_outputs_p : process (present_state, sys_clk_cnt_max)
302
+ fsm_outputs_p : process (present_state, din_last_reg_n, sys_clk_cnt_max)
272
303
begin
273
-
274
304
case present_state is
275
-
276
305
when idle =>
277
306
master_ready <= '1' ;
278
- chip_select_n <= '1' ;
307
+ chip_select_n <= not din_last_reg_n ;
279
308
spi_clk_en <= '0' ;
280
309
first_edge_en <= '0' ;
281
310
second_edge_en <= '0' ;
@@ -298,16 +327,16 @@ begin
298
327
rx_data_vld <= '0' ;
299
328
300
329
when transmit_end =>
301
- master_ready <= '1 ' ;
330
+ master_ready <= '0 ' ;
302
331
chip_select_n <= '0' ;
303
332
spi_clk_en <= '0' ;
304
333
first_edge_en <= '0' ;
305
334
second_edge_en <= '0' ;
306
- rx_data_vld <= '1' ;
335
+ rx_data_vld <= sys_clk_cnt_max ;
307
336
308
- when disable_cs =>
337
+ when transmit_gap =>
309
338
master_ready <= '0' ;
310
- chip_select_n <= '0' ;
339
+ chip_select_n <= not din_last_reg_n ;
311
340
spi_clk_en <= '0' ;
312
341
first_edge_en <= '0' ;
313
342
second_edge_en <= '0' ;
@@ -320,7 +349,6 @@ begin
320
349
first_edge_en <= '0' ;
321
350
second_edge_en <= '0' ;
322
351
rx_data_vld <= '0' ;
323
-
324
352
end case ;
325
353
end process ;
326
354
0 commit comments