├── .project
├── LICENSE.txt
├── Mojo-Base.xise
├── clk_divider.v
├── i2c_master.v
├── ipcore_dir
└── .gitignore
├── iseconfig
├── Mojo-Base.projectmgr
└── mojo_top.xreport
├── read_eeprom.v
├── read_i2c_eeprom.v
├── src
├── 24FC512.v
├── avr_interface.v
├── cclk_detector.v
├── mojo.ucf
├── mojo_top.v
├── serial_rx.v
├── serial_tx.v
└── spi_slave.v
├── syn
└── .gitignore
├── testbench.v
├── testbench_mojo_top.v
└── timer.v
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Mojo-Demo
4 |
5 |
6 |
7 |
8 |
9 | net.sourceforge.veditor.simulateBuilder
10 |
11 |
12 | net.sourceforge.veditor.simulateBuilder.00000000Default.CleanCommand
13 | echo 'Clean'
14 |
15 |
16 | net.sourceforge.veditor.simulateBuilder.00000000Default.buildOrder
17 | 0
18 |
19 |
20 | net.sourceforge.veditor.simulateBuilder.00000000Default.command
21 | echo 'No Build Configuration Specified'
22 |
23 |
24 | net.sourceforge.veditor.simulateBuilder.00000000Default.enable
25 | false
26 |
27 |
28 | net.sourceforge.veditor.simulateBuilder.00000000Default.name
29 | Default
30 |
31 |
32 | net.sourceforge.veditor.simulateBuilder.00000000Default.parser
33 |
34 |
35 |
36 | net.sourceforge.veditor.simulateBuilder.00000000Default.workFolder
37 |
38 |
39 |
40 |
41 |
42 |
43 | net.sourceforge.veditor.HdlNature
44 |
45 |
46 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Embedded Micro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Mojo-Base.xise:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
--------------------------------------------------------------------------------
/clk_divider.v:
--------------------------------------------------------------------------------
1 | module clk_divider(
2 | input wire reset,
3 | input wire clk_in,
4 | output reg clk_out
5 | );
6 |
7 | // ref clock = 50MHz
8 | //i2c_clk = 100kHz
9 | //divider = 500
10 |
11 | parameter DIVIDER = 500;
12 |
13 | reg [15:0] count = 0;
14 |
15 |
16 | always @(posedge clk_in) begin
17 |
18 | if (reset == 1) begin
19 | clk_out = 0;
20 | count = 0;
21 | end //if reset
22 | else begin
23 | if (count == ((DIVIDER/2)-1)) begin
24 | //if (count >= 244) begin
25 | clk_out = ~clk_out;
26 | count = 0;
27 | end else begin
28 | count = count + 1'b1;
29 | end //if count >= 244
30 | end // if reset (else)
31 | end //always
32 |
33 | endmodule
34 |
--------------------------------------------------------------------------------
/i2c_master.v:
--------------------------------------------------------------------------------
1 | `default_nettype none
2 | /*
3 |
4 | References:
5 | https://eewiki.net/pages/viewpage.action?pageId=10125324
6 | http://faculty.lasierra.edu/~ehwang/digitaldesign/public/projects/DE2/I2C/I2C.pdf
7 |
8 | */
9 |
10 | module i2c_master(
11 | input wire clk,
12 | input wire reset,
13 | input wire start,
14 |
15 | input wire [7:0] nbytes_in,
16 | input wire [6:0] addr_in,
17 | input wire rw_in,
18 | input wire [7:0] write_data,
19 | output reg [7:0] read_data,
20 | output reg tx_data_req,
21 | output reg rx_data_ready,
22 |
23 | inout wire sda_w,
24 | output wire scl
25 | );
26 |
27 | //state parameters
28 | localparam STATE_IDLE = 0;
29 | localparam STATE_START = 1;
30 | localparam STATE_ADDR = 2;
31 | localparam STATE_RW = 3;
32 | localparam STATE_ACK = 4;
33 | localparam STATE_READ_ACK = 5;
34 | localparam STATE_TX_DATA = 6;
35 | localparam STATE_RX_DATA = 7;
36 | localparam STATE_STOP = 8;
37 |
38 | localparam READ = 1;
39 | localparam WRITE = 0;
40 | localparam ACK = 0;
41 |
42 | reg [5:0] state;
43 | reg [7:0] bit_count; //bit counter
44 | //local buffers
45 | reg [6:0] addr;
46 | reg [7:0] data;
47 | reg [7:0] nbytes;
48 | reg rw;
49 | reg scl_en = 0;
50 | reg sda;
51 |
52 | //i2c needs to float the sda line when it is high.
53 | //so here I define sda_w which is the wire actually connected to the
54 | // line to be z when sda (logical signal) is 1
55 | assign sda_w = ((sda)==0) ? 1'b0 : 1'bz;
56 |
57 |
58 | //clock
59 | //scl is enabled whenever we are sending or receiving data.
60 | // otherwise it is held at 1
61 | //Note that I also ned to do an ACK check here on the negedge so that I am
62 | // ready to respond on the next posedge below
63 | assign scl = (scl_en == 0) ? 1'b1 : ~clk;
64 |
65 | always @(negedge clk) begin
66 | if (reset == 1) begin
67 | scl_en <= 0;
68 |
69 | end else begin
70 | if ((state == STATE_IDLE) || (state == STATE_START) || (state == STATE_STOP)) begin
71 | scl_en <= 0;
72 | end
73 | else begin
74 | scl_en <= 1;
75 | end
76 |
77 | //I need to check the ack on the rising scl edge (which is the neg edge of clk)
78 | if (state == STATE_ACK) begin
79 | if (0) begin
80 | state <= STATE_IDLE;
81 | end
82 | end
83 | end
84 |
85 | end
86 |
87 |
88 |
89 | //FSM
90 | always @(posedge clk) begin
91 | if (reset == 1) begin
92 | state <= STATE_IDLE;
93 | sda <= 1;
94 | bit_count <= 8'd0;
95 | addr <= 0;
96 | data <= 0;
97 | nbytes <= 0;
98 | rw <= 0;
99 | tx_data_req <= 0;
100 | rx_data_ready <= 0;
101 | end //if reset
102 |
103 | else begin
104 | case(state)
105 |
106 | STATE_IDLE: begin //idle
107 | sda <= 1;
108 | if (start) begin
109 | state <= STATE_START;
110 | end //if start
111 | end
112 |
113 |
114 | STATE_START: begin //start
115 | state <= STATE_ADDR;
116 | sda <= 0; //send start condition
117 | //latch in all the values
118 | addr <= addr_in;
119 | nbytes <= nbytes_in;
120 | rw <= rw_in;
121 | if (rw_in == WRITE) begin
122 | tx_data_req <= 1; //request the first byte of data
123 | end
124 | bit_count <= 6; //addr is only 7 bits long, not 8
125 | end //state_start
126 |
127 |
128 | STATE_ADDR: begin //send slave address
129 | sda <= addr[bit_count];
130 | if (bit_count == 0) begin
131 | state <= STATE_RW;
132 | end
133 | else begin
134 | bit_count <= bit_count - 1'b1;
135 | end
136 | end //state_addr
137 |
138 |
139 | STATE_RW: begin //send R/W bit
140 | sda <= rw;
141 | state <= STATE_ACK;
142 | end //state_rw
143 |
144 |
145 | STATE_ACK: begin
146 | //release the sda line and await ack
147 | sda <= 1;
148 | //Ack is checked on the next rising edge of scl (neg edge of clk)
149 | //So I just assume that it is all ok and set the next state here
150 | //if there is no ack then the state will be overwritten when it is checked
151 |
152 | tx_data_req <= 0; //time is up. if the data isn't in tx by now it is too late!
153 |
154 | //now we have to decide what to do next.
155 | if (nbytes == 0) begin
156 | //there is no data left to read/write
157 | if (start == 1) begin
158 | //repeat start condition
159 | sda <= 1;
160 | state <= STATE_START;
161 | end else begin
162 | //we are done
163 | sda <= 1; //idle state is high
164 | state <= STATE_STOP;
165 | end //if start == 1
166 |
167 | end else begin
168 | //we have more data to read/write
169 | if (rw == WRITE) begin
170 | data <= write_data; //latch in the new data byte
171 | bit_count <= 7; //8 data bits
172 | state <= STATE_TX_DATA;
173 | end else begin
174 | // Read data
175 | bit_count <= 7; //8 data bits
176 | state <= STATE_RX_DATA;
177 | end //if rw_buf == WRITE
178 | end //if nbytes_buf == 0
179 |
180 |
181 | end //state_ack
182 |
183 |
184 |
185 | STATE_TX_DATA: begin
186 | sda <= data[bit_count];
187 | if (nbytes > 0) begin
188 | tx_data_req <= 1; //if there are more bytes to write, then request the next one
189 | end
190 | if (bit_count == 0) begin
191 | //byte transfer complete
192 | state <= STATE_ACK;
193 | nbytes <= nbytes - 1'b1;
194 | end
195 | else begin
196 | bit_count <= bit_count - 1'b1;
197 | end
198 | end //state_tx_data
199 |
200 |
201 |
202 | STATE_RX_DATA: begin
203 | data[bit_count] <= sda_w;
204 | if (bit_count == 0) begin
205 | //byte transfer complete
206 | state <= STATE_ACK;
207 | read_data[7:1] <= data[7:1];
208 | read_data[0] <= sda_w;
209 | rx_data_ready <= 1;
210 | nbytes <= nbytes - 1'b1;
211 | end
212 | else begin
213 | bit_count <= bit_count - 1'b1;
214 | rx_data_ready <= 0;
215 | end
216 | end //state_rx_data
217 |
218 |
219 |
220 | STATE_STOP: begin
221 | sda <= 1;
222 | state <= STATE_IDLE;
223 | end //state_stop
224 |
225 | endcase
226 | end //if reset (else)
227 | end //always
228 |
229 | endmodule
230 |
--------------------------------------------------------------------------------
/ipcore_dir/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcgodfrey/i2c-eeprom/6044391ba0a221a04728c1c1cb80c1bbaded8179/ipcore_dir/.gitignore
--------------------------------------------------------------------------------
/iseconfig/Mojo-Base.projectmgr:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 2
10 | /avr_interface C:|Users|matt|Documents|projects|mojo|mojo-base-project-master|src|avr_interface.v
11 | /avr_interface |home|justin|workspace|Mojo-Tutorials|Mojo-Base|src|avr_interface.v
12 | /read_i2c_eeprom C:|Users|matt|Documents|projects|mojo|i2c-eeprom|read_i2c_eeprom.v
13 |
14 |
15 | instance_name - read_eeprom (C:/Users/matt/Documents/projects/mojo/i2c-eeprom/read_eeprom.v)
16 |
17 | 0
18 | 0
19 | 000000ff00000000000000010000000100000000000000000000000000000000020200000001000000010000006400000150000000020000000000000000000000000200000064ffffffff000000810000000300000002000001500000000100000003000000000000000100000003
20 | true
21 | instance_name - read_eeprom (C:/Users/matt/Documents/projects/mojo/i2c-eeprom/read_eeprom.v)
22 |
23 |
24 |
25 | 1
26 | Configure Target Device
27 | Design Utilities
28 | Implement Design
29 | Implement Design/Map
30 | Implement Design/Place & Route
31 | Implement Design/Translate
32 | Synthesize - XST
33 | User Constraints
34 |
35 |
36 |
37 |
38 | 0
39 | 0
40 | 000000ff00000000000000010000000100000000000000000000000000000000000000000000000234000000010000000100000000000000000000000064ffffffff000000810000000000000001000002340000000100000000
41 | false
42 |
43 |
44 |
45 |
46 | 1
47 |
48 |
49 | 0
50 | 0
51 | 000000ff000000000000000100000000000000000100000000000000000000000000000000000003a3000000040101000100000000000000000000000064ffffffff000000810000000000000004000000770000000100000000000000c50000000100000000000000790000000100000000000001ee0000000100000000
52 | false
53 | avr_interface.v
54 |
55 |
56 |
57 | 1
58 | work
59 |
60 |
61 | 0
62 | 0
63 | 000000ff00000000000000010000000000000000010000000000000000000000000000000000000109000000010001000100000000000000000000000064ffffffff000000810000000000000001000001090000000100000000
64 | false
65 | work
66 |
67 | 000000ff00000000000000020000010b0000011201000000040100000002
68 | Implementation
69 |
70 |
71 | 1
72 | Design Utilities
73 |
74 |
75 |
76 |
77 | 0
78 | 0
79 | 000000ff00000000000000010000000100000000000000000000000000000000000000000000000157000000010000000100000000000000000000000064ffffffff000000810000000000000001000001570000000100000000
80 | false
81 |
82 |
83 |
84 |
85 | 1
86 |
87 |
88 |
89 |
90 | 0
91 | 0
92 | 000000ff00000000000000010000000100000000000000000000000000000000000000000000000234000000010000000100000000000000000000000064ffffffff000000810000000000000001000002340000000100000000
93 | false
94 |
95 |
96 |
97 |
98 | 2
99 | /avr_interface C:|Users|matt|Documents|projects|mojo|mojo-base-project-master|src|avr_interface.v
100 |
101 |
102 | testbench (C:/Users/matt/Documents/projects/mojo/mojo-base-project-master/testbench.v)
103 |
104 | 3
105 | 0
106 | 000000ff00000000000000010000000100000000000000000000000000000000020200000001000000010000006400000150000000020000000000000000000000000200000064ffffffff000000810000000300000002000001500000000100000003000000000000000100000003
107 | false
108 | testbench (C:/Users/matt/Documents/projects/mojo/mojo-base-project-master/testbench.v)
109 |
110 |
111 |
112 | 1
113 | Design Utilities
114 |
115 |
116 |
117 |
118 | 0
119 | 0
120 | 000000ff00000000000000010000000100000000000000000000000000000000000000000000000157000000010000000100000000000000000000000064ffffffff000000810000000000000001000001570000000100000000
121 | false
122 |
123 |
124 |
125 |
126 | 1
127 |
128 |
129 |
130 |
131 | 0
132 | 0
133 | 000000ff00000000000000010000000100000000000000000000000000000000000000000000000157000000010000000100000000000000000000000064ffffffff000000810000000000000001000001570000000100000000
134 | false
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/iseconfig/mojo_top.xreport:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2016-03-09T21:00:40
5 | mojo_top
6 | 2016-03-09T20:48:44
7 | C:/Users/matt/Documents/projects/mojo/i2c-eeprom/iseconfig/mojo_top.xreport
8 | C:/Users/matt/Documents/projects/mojo/i2c-eeprom/syn\
9 | 2016-03-05T00:05:56
10 | false
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/read_eeprom.v:
--------------------------------------------------------------------------------
1 | /*
2 | read_eeprom.v
3 |
4 | High Level module to read data from an i2c eeprom device.
5 |
6 | inputs are:
7 | - eeprom chip i2c slave address [7 bit]
8 | - memory address to read from [16 bit]
9 | - number of bytes to read [8 bit]
10 | - start flag to begin the read operation [1-bit]
11 |
12 | outputs are:
13 | - data_out [8-bits]
14 | - byte-ready [1-bit]
15 |
16 | The new byte is placed in data_out as it is read and the byte-ready
17 | flag is set
18 |
19 | There are then a number of lines which communicate with the i1c_master
20 | module which handles the actual communication with the eeprom chip.
21 |
22 | This module handles the sending and receiving of bytes through the i2c module
23 | This includes sending the slave address and memory address, the repeated start
24 | signal and then reading the requested number of bytes.
25 |
26 | The i2c_master module handles the lower level sending/receiving bytes with the actual chip.
27 |
28 |
29 | IDLE
30 | |
31 | | start signal high
32 | | Latch in slave addr, mem addr and nbytes
33 | V
34 | START
35 | |
36 | | set i2c control lines (addr, rw, etc) ready for address write
37 | | set nbytes=2 (16bit address)
38 | V
39 | WRITE_ADDR
40 | |
41 | | For both memory address bytes:
42 | | Wait for tx_data_req to go high (i1c requesting data) and then set it to the mem addr
43 | V
44 | READ_ADDR
45 | |
46 | | Send repeat start
47 | | While nbytes>0, wait for rx_data_ready, set data_out and byte ready
48 | V
49 | IDLE
50 |
51 | */
52 |
53 |
54 | module read_eeprom(
55 | //inputs
56 | input wire clk,
57 | input wire reset,
58 | input wire [6:0] slave_addr_w,
59 | input wire [15:0] mem_addr_w,
60 | input wire [7:0] read_nbytes_w,
61 | input wire start,
62 |
63 | //outputs
64 | output reg [7:0] data_out,
65 | output reg byte_ready,
66 |
67 | //i2c master comms lines
68 | output reg [6:0] i2c_slave_addr,
69 | output reg i2c_rw,
70 | output reg [7:0] i2c_write_data,
71 | output reg [7:0] i2c_nbytes,
72 | input wire [7:0] i2c_read_data,
73 | input wire i2c_tx_data_req,
74 | input wire i2c_rx_data_ready,
75 | output reg i2c_start,
76 | output reg busy
77 | );
78 |
79 |
80 | //state params
81 | localparam STATE_IDLE = 0;
82 | localparam STATE_START = 1;
83 | localparam STATE_WRITE_ADDR = 2;
84 | localparam STATE_REP_START = 3;
85 | localparam STATE_READ_DATA = 4;
86 |
87 | localparam READ = 1;
88 | localparam WRITE = 0;
89 |
90 | //local buffers to save the transfer information (device slave addr,
91 | // memory addr, etc) when the transfer is started
92 | reg [3:0] state;
93 | reg [6:0] slave_addr;
94 | reg [15:0] mem_addr;
95 | reg [7:0] read_nbytes;
96 | //output register definitions
97 | reg waiting_for_tx;
98 | reg read_prev_data;
99 | reg [7:0] byte_count;
100 |
101 |
102 | always @(posedge clk) begin
103 |
104 | if (reset == 1) begin
105 | i2c_slave_addr <= 0;
106 | i2c_rw <= 0;
107 | i2c_write_data <= 0;
108 | i2c_start <= 0;
109 | i2c_nbytes <= 0;
110 |
111 | data_out <= 0;
112 | byte_ready <= 0;
113 |
114 | mem_addr <= 0;
115 | slave_addr <= 0;
116 | read_nbytes <= 0;
117 | byte_count <= 0;
118 | waiting_for_tx <= 0;
119 |
120 | busy <= 0;
121 |
122 | state <= STATE_IDLE;
123 |
124 | end else begin
125 |
126 | case(state)
127 |
128 | STATE_IDLE: begin //idle
129 |
130 | busy <= 0;
131 |
132 | if (start) begin
133 | state <= STATE_START;
134 |
135 | //buffer all the control data
136 | slave_addr <= slave_addr_w;
137 | mem_addr <= mem_addr_w;
138 | read_nbytes <= read_nbytes_w;
139 | end
140 | end //state_idle
141 |
142 |
143 | STATE_START: begin
144 | state <= STATE_WRITE_ADDR;
145 |
146 | //set all the i2c control lines
147 | i2c_slave_addr <= slave_addr;
148 | i2c_rw <= WRITE;
149 | i2c_nbytes <= 2; //2 memory addr bytes
150 | byte_count <= 2;
151 | waiting_for_tx <= 0;
152 |
153 | i2c_start <= 1;
154 | busy <= 1;
155 | end //state_start
156 |
157 |
158 |
159 | STATE_WRITE_ADDR: begin
160 |
161 | if (waiting_for_tx == 0) begin
162 | if (i2c_tx_data_req == 1) begin
163 | waiting_for_tx <= 1;
164 | case (byte_count)
165 | 2: begin
166 | i2c_write_data <= mem_addr[15:8];
167 | byte_count <= byte_count - 1'b1;
168 | end //case 2
169 |
170 | 1: begin
171 | i2c_write_data <= mem_addr[7:0];
172 | byte_count <= byte_count - 1'b1;
173 | state <= STATE_REP_START;
174 | end //case 1
175 | endcase
176 | end//if i2x_tx_data_req
177 | end else begin
178 | if (i2c_tx_data_req == 0) begin
179 | waiting_for_tx <= 0;
180 | end //if i2x_tx_data_req
181 | end //if waiting_for_tx
182 |
183 | end //state WRITE_ADDR
184 |
185 |
186 |
187 | STATE_REP_START: begin
188 | state <= STATE_READ_DATA;
189 | //set conditions for repeated start and change to read mode
190 | i2c_start <= 1;
191 | i2c_rw <= READ;
192 | i2c_nbytes <= read_nbytes;
193 | read_prev_data <= 0;
194 | byte_count <= 0;
195 |
196 | end //state_rep_start
197 |
198 |
199 |
200 | STATE_READ_DATA: begin
201 |
202 | if (read_prev_data == 0) begin
203 | if (i2c_rx_data_ready) begin
204 | data_out <= i2c_read_data;
205 | byte_ready <= 1;
206 | if (byte_count < (read_nbytes-1)) begin
207 | byte_count <= byte_count + 1'b1;
208 | read_prev_data <= 1;
209 | end else begin
210 | //we are done
211 | i2c_start <= 0;
212 | state <= STATE_IDLE;
213 | end // if byte_count < read_nbytes
214 | end //if i2c_rx_data_ready
215 |
216 | end else begin
217 | if (i2c_rx_data_ready == 0) begin
218 | read_prev_data <= 0;
219 | byte_ready <= 0;
220 | end //if i2c_rx_data_ready
221 | end // if read_prev_data
222 |
223 | end //state_read_data
224 |
225 | endcase
226 |
227 | end
228 |
229 | end
230 |
231 | endmodule
232 |
--------------------------------------------------------------------------------
/read_i2c_eeprom.v:
--------------------------------------------------------------------------------
1 | module read_i2c_eeprom(
2 | // 50MHz clock input
3 | input clk,
4 | // Input from reset button (active low)
5 | input rst_n,
6 | // cclk input from AVR, high when AVR is ready
7 | input cclk,
8 | // Outputs to the 8 onboard LEDs
9 | output[7:0]led,
10 | // AVR SPI connections
11 | output spi_miso,
12 | input spi_ss,
13 | input spi_mosi,
14 | input spi_sck,
15 | // AVR ADC channel select
16 | output [3:0] spi_channel,
17 | // Serial connections
18 | input avr_tx, // AVR Tx => FPGA Rx
19 | output avr_rx, // AVR Rx => FPGA Tx
20 | input avr_rx_busy // AVR Rx buffer full
21 |
22 | //i2c User Interface
23 | //output i2c_scl,
24 | //inout i2c_sda
25 | );
26 |
27 | wire reset = ~rst_n; // make reset active high
28 |
29 | // these signals should be high-z when not used
30 | assign spi_miso = 1'bz;
31 | assign avr_rx = 1'bz;
32 | assign spi_channel = 4'bzzzz;
33 |
34 | assign led[5:0] = 6'b000000;
35 | assign led[7] = tick_1s;
36 | assign led[6] = clk_i2c_in;
37 |
38 | wire tick_1s;
39 | wire i2c_clk_in;
40 |
41 | //wire i2c_scl = 1'b1;
42 | //wire i2c_sda = 1'b1;
43 |
44 | //Generate a 1s timer
45 | timer #(.CTR_LEN(26)) second_timer (
46 | //timer second_timer (
47 | .clk(clk),
48 | .reset(reset),
49 | .tick(tick_1s)
50 | );
51 |
52 |
53 | wire i2c_clk_divider_reset = reset;
54 |
55 |
56 | clk_divider i2c_clk_divider (
57 | .reset(i2c_clk_divider_reset),
58 | .clk_in(clk),
59 | .clk_out(i2c_clk_in)
60 | );
61 |
62 |
63 | wire i2c_start;
64 | wire i2c_reset;
65 | wire [7:0] i2c_nbytes;
66 | wire [6:0] i2c_slave_addr;
67 | wire i2c_rw;
68 | wire [7:0] i2c_write_data;
69 | wire [7:0] i2c_read_data;
70 | wire i2c_tx_data_req;
71 | wire i2c_rx_data_ready;
72 | wire i2c_sda;
73 | wire i2c_scl;
74 | wire ready;
75 | wire busy;
76 |
77 | i2c_master i2c (
78 | .clk(i2c_clk_in),
79 | .reset(i2c_reset),
80 | .start(i2c_start),
81 | .nbytes_in(i2c_nbytes),
82 | .addr_in(i2c_slave_addr),
83 | .rw_in(i2c_rw),
84 | .write_data(i2c_write_data),
85 | .read_data(i2c_read_data),
86 | .tx_data_req(i2c_tx_data_req),
87 | .rx_data_ready(i2c_rx_data_ready),
88 | .sda_w(sda_w),
89 | .scl(scl),
90 | .ready(ready),
91 | .busy(busy)
92 | );
93 |
94 | wire [6:0] slave_addr = 7'b1010000;
95 | wire [15:0] mem_addr = 16'h0000;
96 | wire [7:0] read_n_bytes = 8'd1;
97 | wire read_eeprom_reset = 1;
98 |
99 | wire [7:0] read_nbytes = 0;
100 | wire start = 0;
101 | wire [7:0] data_out;
102 | wire byte_ready;
103 |
104 |
105 | read_eeprom instance_name (
106 | .clk(clk),
107 | .reset(read_eeprom_reset),
108 | .slave_addr_w(slave_addr),
109 | .mem_addr_w(mem_addr),
110 | .read_nbytes_w(read_nbytes),
111 | .start(start),
112 | .data_out(data_out),
113 | .byte_ready(byte_ready),
114 | .i2c_slave_addr(i2c_slave_addr),
115 | .i2c_rw(i2c_rw),
116 | .i2c_write_data(i2c_write_data),
117 | .i2c_nbytes(i2c_nbytes),
118 | .i2c_read_data(i2c_read_data),
119 | .i2c_tx_data_req(i2c_tx_data_req),
120 | .i2c_rx_data_ready(i2c_rx_data_ready),
121 | .i2c_start(i2c_start)
122 | );
123 |
124 |
125 | always @(posedge tick_1s) begin
126 | if (reset == 1) begin
127 |
128 | end else begin
129 |
130 | end // reset
131 | end //always
132 |
133 |
134 | /*
135 | //constants
136 | wire [6:0] slave_addr = 7'b1010000;
137 | wire [7:0] mem_addr = 8'b00000000;
138 | wire [7:0] read_n_bytes = 8'd1;
139 |
140 | reg [7:0] data_out;
141 |
142 | //hookup wires
143 | wire [6:0] i2c_slave_addr;
144 | wire i2c_rw;
145 | wire [7:0] i2c_nbytes;
146 | wire [7:0] i2c_write_data;
147 | wire [7:0] i2c_read_data;
148 | wire i2c_tx_data_req;
149 | wire i2c_rx_data_ready;
150 | wire i2c_start;
151 |
152 |
153 |
154 |
155 | /we need to make sure the i2c module is reset *after*
156 | //it's clock has begun
157 | always @(posedge clk_i2c_in) begin
158 |
159 | if (reset == 1) begin
160 |
161 | end else begin
162 | i2c_reset <= 0;
163 | end
164 | end //posedge clk_i2c_in
165 |
166 |
167 | //Every 1s I read a new value from EEPROM
168 | always @(posedge tick_1s) begin
169 |
170 |
171 | end //posedge tick_1s
172 |
173 |
174 |
175 | read_eeprom instance_name (
176 | .clk(clk),
177 | .reset(reset),
178 | .slave_addr_w(slave_addr),
179 | .mem_addr_w(mem_addr),
180 | .read_nbytes_w(read_nbytes),
181 | .start(start),
182 | .data_out(data_out),
183 | .byte_ready(byte_ready),
184 | .i2c_slave_addr(i2c_slave_addr),
185 | .i2c_rw(i2c_rw),
186 | .i2c_write_data(i2c_write_data),
187 | .i2c_nbytes(i2c_nbytes),
188 | .i2c_read_data(i2c_read_data),
189 | .i2c_tx_data_req(i2c_tx_data_req),
190 | .i2c_rx_data_ready(i2c_rx_data_ready),
191 | .i2c_start(i2c_start)
192 | );
193 |
194 |
195 | wire ready;
196 | wire busy;
197 | wire i2c_reset;
198 |
199 |
200 |
201 |
202 | clk_divider i2c_clk_divider (
203 | .reset(reset),
204 | .clk_in(clk),
205 | .clk_out(clk_i2c_in)
206 | );
207 |
208 |
209 | i2c_master instance_name (
210 | .clk(clk_i2c_in),
211 | .reset(i2c_reset),
212 | .start(i2c_start),
213 | .nbytes_in(i2c_nbytes),
214 | .addr_in(i2c_slave_addr),
215 | .rw_in(i2c_rw),
216 | .write_data(i2c_write_data),
217 | .read_data(i2c_read_data),
218 | .tx_data_req(i2c_tx_data_req),
219 | .rx_data_ready(i2c_rx_data_ready),
220 | .sda_w(i2c_sda),
221 | .scl(i2c_scl),
222 | .ready(ready),
223 | .busy(busy)
224 | );
225 |
226 | */
227 |
228 |
229 |
230 |
231 | endmodule
--------------------------------------------------------------------------------
/src/24FC512.v:
--------------------------------------------------------------------------------
1 | // *******************************************************************************************************
2 | // ** **
3 | // ** 24FC512.v - Microchip 24FC512 512K-BIT I2C SERIAL EEPROM (VCC = +1.7V TO +5.5V) **
4 | // ** **
5 | // *******************************************************************************************************
6 | // ** **
7 | // ** This information is distributed under license from Young Engineering. **
8 | // ** COPYRIGHT (c) 2009 YOUNG ENGINEERING **
9 | // ** ALL RIGHTS RESERVED **
10 | // ** **
11 | // ** **
12 | // ** Young Engineering provides design expertise for the digital world **
13 | // ** Started in 1990, Young Engineering offers products and services for your electronic design **
14 | // ** project. We have the expertise in PCB, FPGA, ASIC, firmware, and software design. **
15 | // ** From concept to prototype to production, we can help you. **
16 | // ** **
17 | // ** http://www.young-engineering.com/ **
18 | // ** **
19 | // *******************************************************************************************************
20 | // ** This information is provided to you for your convenience and use with Microchip products only. **
21 | // ** Microchip disclaims all liability arising from this information and its use. **
22 | // ** **
23 | // ** THIS INFORMATION IS PROVIDED "AS IS." MICROCHIP MAKES NO REPRESENTATION OR WARRANTIES OF **
24 | // ** ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO **
25 | // ** THE INFORMATION PROVIDED TO YOU, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, **
26 | // ** PERFORMANCE, MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR PURPOSE. **
27 | // ** MICROCHIP IS NOT LIABLE, UNDER ANY CIRCUMSTANCES, FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL **
28 | // ** DAMAGES, FOR ANY REASON WHATSOEVER. **
29 | // ** **
30 | // ** It is your responsibility to ensure that your application meets with your specifications. **
31 | // ** **
32 | // *******************************************************************************************************
33 | // ** Revision : 1.0 **
34 | // ** Modified Date : 02/04/2009 **
35 | // ** Revision History: **
36 | // ** **
37 | // ** 02/04/2009: Initial design **
38 | // ** **
39 | // *******************************************************************************************************
40 | // ** TABLE OF CONTENTS **
41 | // *******************************************************************************************************
42 | // **---------------------------------------------------------------------------------------------------**
43 | // ** DECLARATIONS **
44 | // **---------------------------------------------------------------------------------------------------**
45 | // **---------------------------------------------------------------------------------------------------**
46 | // ** INITIALIZATION **
47 | // **---------------------------------------------------------------------------------------------------**
48 | // **---------------------------------------------------------------------------------------------------**
49 | // ** CORE LOGIC **
50 | // **---------------------------------------------------------------------------------------------------**
51 | // ** 1.01: START Bit Detection **
52 | // ** 1.02: STOP Bit Detection **
53 | // ** 1.03: Input Shift Register **
54 | // ** 1.04: Input Bit Counter **
55 | // ** 1.05: Control Byte Register **
56 | // ** 1.06: Byte Address Register **
57 | // ** 1.07: Write Data Buffer **
58 | // ** 1.08: Acknowledge Generator **
59 | // ** 1.09: Acknowledge Detect **
60 | // ** 1.10: Write Cycle Timer **
61 | // ** 1.11: Write Cycle Processor **
62 | // ** 1.12: Read Data Multiplexor **
63 | // ** 1.13: Read Data Processor **
64 | // ** 1.14: SDA Data I/O Buffer **
65 | // ** **
66 | // **---------------------------------------------------------------------------------------------------**
67 | // ** DEBUG LOGIC **
68 | // **---------------------------------------------------------------------------------------------------**
69 | // ** 2.01: Memory Data Bytes **
70 | // ** 2.02: Write Data Buffer **
71 | // ** **
72 | // **---------------------------------------------------------------------------------------------------**
73 | // ** TIMING CHECKS **
74 | // **---------------------------------------------------------------------------------------------------**
75 | // ** **
76 | // *******************************************************************************************************
77 |
78 |
79 | `timescale 1ns/10ps
80 |
81 | module M24FC512 (A0, A1, A2, WP, SDA, SCL, RESET);
82 |
83 | input A0; // chip select bit
84 | input A1; // chip select bit
85 | input A2; // chip select bit
86 |
87 | input WP; // write protect pin
88 |
89 | inout SDA; // serial data I/O
90 | input SCL; // serial data clock
91 |
92 | input RESET; // system reset
93 |
94 |
95 | // *******************************************************************************************************
96 | // ** DECLARATIONS **
97 | // *******************************************************************************************************
98 |
99 | reg SDA_DO; // serial data - output
100 | reg SDA_OE; // serial data - output enable
101 |
102 | wire SDA_DriveEnable; // serial data output enable
103 | reg SDA_DriveEnableDlyd; // serial data output enable - delayed
104 |
105 | wire [02:00] ChipAddress; // hardwired chip address
106 |
107 | reg [03:00] BitCounter; // serial bit counter
108 |
109 | reg START_Rcvd; // START bit received flag
110 | reg STOP_Rcvd; // STOP bit received flag
111 | reg CTRL_Rcvd; // control byte received flag
112 | reg ADHI_Rcvd; // byte address hi received flag
113 | reg ADLO_Rcvd; // byte address lo received flag
114 | reg MACK_Rcvd; // master acknowledge received flag
115 |
116 | reg WrCycle; // memory write cycle
117 | reg RdCycle; // memory read cycle
118 |
119 | reg [07:00] ShiftRegister; // input data shift register
120 |
121 | reg [07:00] ControlByte; // control byte register
122 | wire RdWrBit; // read/write control bit
123 |
124 | reg [15:00] StartAddress; // memory access starting address
125 | reg [06:00] PageAddress; // memory page address
126 |
127 | reg [07:00] WrDataByte [0:127]; // memory write data buffer
128 | wire [07:00] RdDataByte; // memory read data
129 |
130 | reg [15:00] WrCounter; // write buffer counter
131 |
132 | reg [06:00] WrPointer; // write buffer pointer
133 | reg [15:00] RdPointer; // read address pointer
134 |
135 | reg WriteActive; // memory write cycle active
136 |
137 | reg [07:00] MemoryBlock [0:65535]; // EEPROM data memory array
138 |
139 | integer LoopIndex; // iterative loop index
140 |
141 | integer tAA; // timing parameter
142 | integer tWC; // timing parameter
143 |
144 |
145 | // *******************************************************************************************************
146 | // ** INITIALIZATION **
147 | // *******************************************************************************************************
148 |
149 | initial begin
150 | `ifdef VCC_1_7V_TO_2_5V
151 | tAA = 900; // SCL to SDA output delay
152 | tWC = 5000000; // memory write cycle time
153 | `else
154 | `ifdef VCC_2_5V_TO_5_5V
155 | tAA = 400; // SCL to SDA output delay
156 | tWC = 5000000; // memory write cycle time
157 | `else
158 | tAA = 400; // SCL to SDA output delay
159 | tWC = 5000000; // memory write cycle time
160 | `endif
161 | `endif
162 | end
163 |
164 | initial begin
165 | SDA_DO = 0;
166 | SDA_OE = 0;
167 | end
168 |
169 | initial begin
170 | START_Rcvd = 0;
171 | STOP_Rcvd = 0;
172 | CTRL_Rcvd = 0;
173 | ADHI_Rcvd = 0;
174 | ADLO_Rcvd = 0;
175 | MACK_Rcvd = 0;
176 | end
177 |
178 | initial begin
179 | BitCounter = 0;
180 | ControlByte = 0;
181 | end
182 |
183 | initial begin
184 | WrCycle = 0;
185 | RdCycle = 0;
186 |
187 | WriteActive = 0;
188 | end
189 |
190 | assign ChipAddress = {A2,A1,A0};
191 |
192 |
193 | // *******************************************************************************************************
194 | // ** CORE LOGIC **
195 | // *******************************************************************************************************
196 | // -------------------------------------------------------------------------------------------------------
197 | // 1.01: START Bit Detection
198 | // -------------------------------------------------------------------------------------------------------
199 |
200 | always @(negedge SDA) begin
201 | if (SCL == 1) begin
202 | START_Rcvd <= 1;
203 | STOP_Rcvd <= 0;
204 | CTRL_Rcvd <= 0;
205 | ADHI_Rcvd <= 0;
206 | ADLO_Rcvd <= 0;
207 | MACK_Rcvd <= 0;
208 |
209 | WrCycle <= #1 0;
210 | RdCycle <= #1 0;
211 |
212 | BitCounter <= 0;
213 | end
214 | end
215 |
216 | // -------------------------------------------------------------------------------------------------------
217 | // 1.02: STOP Bit Detection
218 | // -------------------------------------------------------------------------------------------------------
219 |
220 | always @(posedge SDA) begin
221 | if (SCL == 1) begin
222 | START_Rcvd <= 0;
223 | STOP_Rcvd <= 1;
224 | CTRL_Rcvd <= 0;
225 | ADHI_Rcvd <= 0;
226 | ADLO_Rcvd <= 0;
227 | MACK_Rcvd <= 0;
228 |
229 | WrCycle <= #1 0;
230 | RdCycle <= #1 0;
231 |
232 | BitCounter <= 10;
233 | end
234 | end
235 |
236 | // -------------------------------------------------------------------------------------------------------
237 | // 1.03: Input Shift Register
238 | // -------------------------------------------------------------------------------------------------------
239 |
240 | always @(posedge SCL) begin
241 | ShiftRegister[00] <= SDA;
242 | ShiftRegister[01] <= ShiftRegister[00];
243 | ShiftRegister[02] <= ShiftRegister[01];
244 | ShiftRegister[03] <= ShiftRegister[02];
245 | ShiftRegister[04] <= ShiftRegister[03];
246 | ShiftRegister[05] <= ShiftRegister[04];
247 | ShiftRegister[06] <= ShiftRegister[05];
248 | ShiftRegister[07] <= ShiftRegister[06];
249 | end
250 |
251 | // -------------------------------------------------------------------------------------------------------
252 | // 1.04: Input Bit Counter
253 | // -------------------------------------------------------------------------------------------------------
254 |
255 | always @(posedge SCL) begin
256 | if (BitCounter < 10) BitCounter <= BitCounter + 1;
257 | end
258 |
259 | // -------------------------------------------------------------------------------------------------------
260 | // 1.05: Control Byte Register
261 | // -------------------------------------------------------------------------------------------------------
262 |
263 | always @(negedge SCL) begin
264 | if (START_Rcvd & (BitCounter == 8)) begin
265 | if (!WriteActive & (ShiftRegister[07:01] == {4'b1010,ChipAddress[02:00]})) begin
266 | if (ShiftRegister[00] == 0) WrCycle <= 1;
267 | if (ShiftRegister[00] == 1) RdCycle <= 1;
268 |
269 | ControlByte <= ShiftRegister[07:00];
270 |
271 | CTRL_Rcvd <= 1;
272 | end
273 |
274 | START_Rcvd <= 0;
275 | end
276 | end
277 |
278 | assign RdWrBit = ControlByte[00];
279 |
280 | // -------------------------------------------------------------------------------------------------------
281 | // 1.06: Byte Address Register
282 | // -------------------------------------------------------------------------------------------------------
283 |
284 | always @(negedge SCL) begin
285 | if (CTRL_Rcvd & (BitCounter == 8)) begin
286 | if (RdWrBit == 0) begin
287 | StartAddress[15:08] <= ShiftRegister[07:00];
288 | RdPointer[15:08] <= ShiftRegister[07:00];
289 |
290 | ADHI_Rcvd <= 1;
291 | end
292 |
293 | WrCounter <= 0;
294 | WrPointer <= 0;
295 |
296 | CTRL_Rcvd <= 0;
297 | end
298 | end
299 |
300 | always @(negedge SCL) begin
301 | if (ADHI_Rcvd & (BitCounter == 8)) begin
302 | if (RdWrBit == 0) begin
303 | StartAddress[07:00] <= ShiftRegister[07:00];
304 | RdPointer[07:00] <= ShiftRegister[07:00];
305 |
306 | ADLO_Rcvd <= 1;
307 | end
308 |
309 | WrCounter <= 0;
310 | WrPointer <= 0;
311 |
312 | ADHI_Rcvd <= 0;
313 | end
314 | end
315 |
316 | // -------------------------------------------------------------------------------------------------------
317 | // 1.07: Write Data Buffer
318 | // -------------------------------------------------------------------------------------------------------
319 |
320 | always @(negedge SCL) begin
321 | if (ADLO_Rcvd & (BitCounter == 8)) begin
322 | if (RdWrBit == 0) begin
323 | WrDataByte[WrPointer] <= ShiftRegister[07:00];
324 |
325 | WrCounter <= WrCounter + 1;
326 | WrPointer <= WrPointer + 1;
327 | end
328 | end
329 | end
330 |
331 | // -------------------------------------------------------------------------------------------------------
332 | // 1.08: Acknowledge Generator
333 | // -------------------------------------------------------------------------------------------------------
334 |
335 | always @(negedge SCL) begin
336 | if (!WriteActive) begin
337 | if (BitCounter == 8) begin
338 | if (WrCycle | (START_Rcvd & (ShiftRegister[07:01] == {4'b1010,ChipAddress[02:00]}))) begin
339 | SDA_DO <= 0;
340 | SDA_OE <= 1;
341 | end
342 | end
343 | if (BitCounter == 9) begin
344 | BitCounter <= 0;
345 |
346 | if (!RdCycle) begin
347 | SDA_DO <= 0;
348 | SDA_OE <= 0;
349 | end
350 | end
351 | end
352 | end
353 |
354 | // -------------------------------------------------------------------------------------------------------
355 | // 1.09: Acknowledge Detect
356 | // -------------------------------------------------------------------------------------------------------
357 |
358 | always @(posedge SCL) begin
359 | if (RdCycle & (BitCounter == 8)) begin
360 | if ((SDA == 0) & (SDA_OE == 0)) MACK_Rcvd <= 1;
361 | end
362 | end
363 |
364 | always @(negedge SCL) MACK_Rcvd <= 0;
365 |
366 | // -------------------------------------------------------------------------------------------------------
367 | // 1.10: Write Cycle Timer
368 | // -------------------------------------------------------------------------------------------------------
369 |
370 | always @(posedge STOP_Rcvd) begin
371 | if (WrCycle & (WP == 0) & (WrCounter > 0)) begin
372 | WriteActive = 1;
373 | #(tWC);
374 | WriteActive = 0;
375 | end
376 | end
377 |
378 | always @(posedge STOP_Rcvd) begin
379 | #(1.0);
380 | STOP_Rcvd = 0;
381 | end
382 |
383 | // -------------------------------------------------------------------------------------------------------
384 | // 1.11: Write Cycle Processor
385 | // -------------------------------------------------------------------------------------------------------
386 |
387 | always @(negedge WriteActive) begin
388 | for (LoopIndex = 0; LoopIndex < WrCounter; LoopIndex = LoopIndex + 1) begin
389 | PageAddress = StartAddress[06:00] + LoopIndex;
390 |
391 | MemoryBlock[{StartAddress[15:07],PageAddress[06:00]}] = WrDataByte[LoopIndex[06:00]];
392 | end
393 | end
394 |
395 | // -------------------------------------------------------------------------------------------------------
396 | // 1.12: Read Data Multiplexor
397 | // -------------------------------------------------------------------------------------------------------
398 |
399 | always @(negedge SCL) begin
400 | if (BitCounter == 8) begin
401 | if (WrCycle & ADLO_Rcvd) begin
402 | RdPointer <= StartAddress + WrPointer + 1;
403 | end
404 | if (RdCycle) begin
405 | RdPointer <= RdPointer + 1;
406 | end
407 | end
408 | end
409 |
410 | assign RdDataByte = MemoryBlock[RdPointer[15:00]];
411 |
412 | // -------------------------------------------------------------------------------------------------------
413 | // 1.13: Read Data Processor
414 | // -------------------------------------------------------------------------------------------------------
415 |
416 | always @(negedge SCL) begin
417 | if (RdCycle) begin
418 | if (BitCounter == 8) begin
419 | SDA_DO <= 0;
420 | SDA_OE <= 0;
421 | end
422 | else if (BitCounter == 9) begin
423 | SDA_DO <= RdDataByte[07];
424 |
425 | if (MACK_Rcvd) SDA_OE <= 1;
426 | end
427 | else begin
428 | SDA_DO <= RdDataByte[7-BitCounter];
429 | end
430 | end
431 | end
432 |
433 | // -------------------------------------------------------------------------------------------------------
434 | // 1.14: SDA Data I/O Buffer
435 | // -------------------------------------------------------------------------------------------------------
436 |
437 | bufif1 (SDA, 1'b0, SDA_DriveEnableDlyd);
438 |
439 | assign SDA_DriveEnable = !SDA_DO & SDA_OE;
440 | always @(SDA_DriveEnable) SDA_DriveEnableDlyd <= #(tAA) SDA_DriveEnable;
441 |
442 |
443 | // *******************************************************************************************************
444 | // ** DEBUG LOGIC **
445 | // *******************************************************************************************************
446 | // -------------------------------------------------------------------------------------------------------
447 | // 2.01: Memory Data Bytes
448 | // -------------------------------------------------------------------------------------------------------
449 |
450 | wire [07:00] MemoryByte_000 = MemoryBlock[00];
451 | wire [07:00] MemoryByte_001 = MemoryBlock[01];
452 | wire [07:00] MemoryByte_002 = MemoryBlock[02];
453 | wire [07:00] MemoryByte_003 = MemoryBlock[03];
454 | wire [07:00] MemoryByte_004 = MemoryBlock[04];
455 | wire [07:00] MemoryByte_005 = MemoryBlock[05];
456 | wire [07:00] MemoryByte_006 = MemoryBlock[06];
457 | wire [07:00] MemoryByte_007 = MemoryBlock[07];
458 | wire [07:00] MemoryByte_008 = MemoryBlock[08];
459 | wire [07:00] MemoryByte_009 = MemoryBlock[09];
460 | wire [07:00] MemoryByte_00A = MemoryBlock[10];
461 | wire [07:00] MemoryByte_00B = MemoryBlock[11];
462 | wire [07:00] MemoryByte_00C = MemoryBlock[12];
463 | wire [07:00] MemoryByte_00D = MemoryBlock[13];
464 | wire [07:00] MemoryByte_00E = MemoryBlock[14];
465 | wire [07:00] MemoryByte_00F = MemoryBlock[15];
466 |
467 | // -------------------------------------------------------------------------------------------------------
468 | // 2.02: Write Data Buffer
469 | // -------------------------------------------------------------------------------------------------------
470 |
471 | wire [07:00] WriteData_00 = WrDataByte[00];
472 | wire [07:00] WriteData_01 = WrDataByte[01];
473 | wire [07:00] WriteData_02 = WrDataByte[02];
474 | wire [07:00] WriteData_03 = WrDataByte[03];
475 | wire [07:00] WriteData_04 = WrDataByte[04];
476 | wire [07:00] WriteData_05 = WrDataByte[05];
477 | wire [07:00] WriteData_06 = WrDataByte[06];
478 | wire [07:00] WriteData_07 = WrDataByte[07];
479 | wire [07:00] WriteData_08 = WrDataByte[08];
480 | wire [07:00] WriteData_09 = WrDataByte[09];
481 | wire [07:00] WriteData_0A = WrDataByte[10];
482 | wire [07:00] WriteData_0B = WrDataByte[11];
483 | wire [07:00] WriteData_0C = WrDataByte[12];
484 | wire [07:00] WriteData_0D = WrDataByte[13];
485 | wire [07:00] WriteData_0E = WrDataByte[14];
486 | wire [07:00] WriteData_0F = WrDataByte[15];
487 |
488 | wire [07:00] WriteData_10 = WrDataByte[16];
489 | wire [07:00] WriteData_11 = WrDataByte[17];
490 | wire [07:00] WriteData_12 = WrDataByte[18];
491 | wire [07:00] WriteData_13 = WrDataByte[19];
492 | wire [07:00] WriteData_14 = WrDataByte[20];
493 | wire [07:00] WriteData_15 = WrDataByte[21];
494 | wire [07:00] WriteData_16 = WrDataByte[22];
495 | wire [07:00] WriteData_17 = WrDataByte[23];
496 | wire [07:00] WriteData_18 = WrDataByte[24];
497 | wire [07:00] WriteData_19 = WrDataByte[25];
498 | wire [07:00] WriteData_1A = WrDataByte[26];
499 | wire [07:00] WriteData_1B = WrDataByte[27];
500 | wire [07:00] WriteData_1C = WrDataByte[28];
501 | wire [07:00] WriteData_1D = WrDataByte[29];
502 | wire [07:00] WriteData_1E = WrDataByte[30];
503 | wire [07:00] WriteData_1F = WrDataByte[31];
504 |
505 | wire [07:00] WriteData_20 = WrDataByte[32];
506 | wire [07:00] WriteData_21 = WrDataByte[33];
507 | wire [07:00] WriteData_22 = WrDataByte[34];
508 | wire [07:00] WriteData_23 = WrDataByte[35];
509 | wire [07:00] WriteData_24 = WrDataByte[36];
510 | wire [07:00] WriteData_25 = WrDataByte[37];
511 | wire [07:00] WriteData_26 = WrDataByte[38];
512 | wire [07:00] WriteData_27 = WrDataByte[39];
513 | wire [07:00] WriteData_28 = WrDataByte[40];
514 | wire [07:00] WriteData_29 = WrDataByte[41];
515 | wire [07:00] WriteData_2A = WrDataByte[42];
516 | wire [07:00] WriteData_2B = WrDataByte[43];
517 | wire [07:00] WriteData_2C = WrDataByte[44];
518 | wire [07:00] WriteData_2D = WrDataByte[45];
519 | wire [07:00] WriteData_2E = WrDataByte[46];
520 | wire [07:00] WriteData_2F = WrDataByte[47];
521 |
522 | wire [07:00] WriteData_30 = WrDataByte[48];
523 | wire [07:00] WriteData_31 = WrDataByte[49];
524 | wire [07:00] WriteData_32 = WrDataByte[50];
525 | wire [07:00] WriteData_33 = WrDataByte[51];
526 | wire [07:00] WriteData_34 = WrDataByte[52];
527 | wire [07:00] WriteData_35 = WrDataByte[53];
528 | wire [07:00] WriteData_36 = WrDataByte[54];
529 | wire [07:00] WriteData_37 = WrDataByte[55];
530 | wire [07:00] WriteData_38 = WrDataByte[56];
531 | wire [07:00] WriteData_39 = WrDataByte[57];
532 | wire [07:00] WriteData_3A = WrDataByte[58];
533 | wire [07:00] WriteData_3B = WrDataByte[59];
534 | wire [07:00] WriteData_3C = WrDataByte[60];
535 | wire [07:00] WriteData_3D = WrDataByte[61];
536 | wire [07:00] WriteData_3E = WrDataByte[62];
537 | wire [07:00] WriteData_3F = WrDataByte[63];
538 |
539 | wire [07:00] WriteData_40 = WrDataByte[64];
540 | wire [07:00] WriteData_41 = WrDataByte[65];
541 | wire [07:00] WriteData_42 = WrDataByte[66];
542 | wire [07:00] WriteData_43 = WrDataByte[67];
543 | wire [07:00] WriteData_44 = WrDataByte[68];
544 | wire [07:00] WriteData_45 = WrDataByte[69];
545 | wire [07:00] WriteData_46 = WrDataByte[70];
546 | wire [07:00] WriteData_47 = WrDataByte[71];
547 | wire [07:00] WriteData_48 = WrDataByte[72];
548 | wire [07:00] WriteData_49 = WrDataByte[73];
549 | wire [07:00] WriteData_4A = WrDataByte[74];
550 | wire [07:00] WriteData_4B = WrDataByte[75];
551 | wire [07:00] WriteData_4C = WrDataByte[76];
552 | wire [07:00] WriteData_4D = WrDataByte[77];
553 | wire [07:00] WriteData_4E = WrDataByte[78];
554 | wire [07:00] WriteData_4F = WrDataByte[79];
555 |
556 | wire [07:00] WriteData_50 = WrDataByte[80];
557 | wire [07:00] WriteData_51 = WrDataByte[81];
558 | wire [07:00] WriteData_52 = WrDataByte[82];
559 | wire [07:00] WriteData_53 = WrDataByte[83];
560 | wire [07:00] WriteData_54 = WrDataByte[84];
561 | wire [07:00] WriteData_55 = WrDataByte[85];
562 | wire [07:00] WriteData_56 = WrDataByte[86];
563 | wire [07:00] WriteData_57 = WrDataByte[87];
564 | wire [07:00] WriteData_58 = WrDataByte[88];
565 | wire [07:00] WriteData_59 = WrDataByte[89];
566 | wire [07:00] WriteData_5A = WrDataByte[90];
567 | wire [07:00] WriteData_5B = WrDataByte[91];
568 | wire [07:00] WriteData_5C = WrDataByte[92];
569 | wire [07:00] WriteData_5D = WrDataByte[93];
570 | wire [07:00] WriteData_5E = WrDataByte[94];
571 | wire [07:00] WriteData_5F = WrDataByte[95];
572 |
573 | wire [07:00] WriteData_60 = WrDataByte[96];
574 | wire [07:00] WriteData_61 = WrDataByte[97];
575 | wire [07:00] WriteData_62 = WrDataByte[98];
576 | wire [07:00] WriteData_63 = WrDataByte[99];
577 | wire [07:00] WriteData_64 = WrDataByte[100];
578 | wire [07:00] WriteData_65 = WrDataByte[101];
579 | wire [07:00] WriteData_66 = WrDataByte[102];
580 | wire [07:00] WriteData_67 = WrDataByte[103];
581 | wire [07:00] WriteData_68 = WrDataByte[104];
582 | wire [07:00] WriteData_69 = WrDataByte[105];
583 | wire [07:00] WriteData_6A = WrDataByte[106];
584 | wire [07:00] WriteData_6B = WrDataByte[107];
585 | wire [07:00] WriteData_6C = WrDataByte[108];
586 | wire [07:00] WriteData_6D = WrDataByte[109];
587 | wire [07:00] WriteData_6E = WrDataByte[110];
588 | wire [07:00] WriteData_6F = WrDataByte[111];
589 |
590 | wire [07:00] WriteData_70 = WrDataByte[112];
591 | wire [07:00] WriteData_71 = WrDataByte[113];
592 | wire [07:00] WriteData_72 = WrDataByte[114];
593 | wire [07:00] WriteData_73 = WrDataByte[115];
594 | wire [07:00] WriteData_74 = WrDataByte[116];
595 | wire [07:00] WriteData_75 = WrDataByte[117];
596 | wire [07:00] WriteData_76 = WrDataByte[118];
597 | wire [07:00] WriteData_77 = WrDataByte[119];
598 | wire [07:00] WriteData_78 = WrDataByte[120];
599 | wire [07:00] WriteData_79 = WrDataByte[121];
600 | wire [07:00] WriteData_7A = WrDataByte[122];
601 | wire [07:00] WriteData_7B = WrDataByte[123];
602 | wire [07:00] WriteData_7C = WrDataByte[124];
603 | wire [07:00] WriteData_7D = WrDataByte[125];
604 | wire [07:00] WriteData_7E = WrDataByte[126];
605 | wire [07:00] WriteData_7F = WrDataByte[127];
606 |
607 |
608 | // *******************************************************************************************************
609 | // ** TIMING CHECKS **
610 | // *******************************************************************************************************
611 |
612 | wire TimingCheckEnable = (RESET == 0) & (SDA_OE == 0);
613 | wire tstSTOP = STOP_Rcvd;
614 |
615 | specify
616 | `ifdef VCC_1_7V_TO_2_5V
617 | specparam
618 | tHI = 600, // SCL pulse width - high
619 | tLO = 1300, // SCL pulse width - low
620 | tSU_STA = 600, // SCL to SDA setup time
621 | tHD_STA = 600, // SCL to SDA hold time
622 | tSU_DAT = 100, // SDA to SCL setup time
623 | tSU_STO = 600, // SCL to SDA setup time
624 | tSU_WP = 600, // WP to SDA setup time
625 | tHD_WP = 1300, // WP to SDA hold time
626 | tBUF = 1300; // Bus free time
627 | `else
628 | `ifdef VCC_2_5V_TO_5_5V
629 | specparam
630 | tHI = 500, // SCL pulse width - high
631 | tLO = 500, // SCL pulse width - low
632 | tSU_STA = 250, // SCL to SDA setup time
633 | tHD_STA = 250, // SCL to SDA hold time
634 | tSU_DAT = 100, // SDA to SCL setup time
635 | tSU_STO = 250, // SCL to SDA setup time
636 | tSU_WP = 600, // WP to SDA setup time
637 | tHD_WP = 1300, // WP to SDA hold time
638 | tBUF = 500; // Bus free time
639 | `else
640 | specparam
641 | tHI = 500, // SCL pulse width - high
642 | tLO = 500, // SCL pulse width - low
643 | tSU_STA = 250, // SCL to SDA setup time
644 | tHD_STA = 250, // SCL to SDA hold time
645 | tSU_DAT = 100, // SDA to SCL setup time
646 | tSU_STO = 250, // SCL to SDA setup time
647 | tSU_WP = 600, // WP to SDA setup time
648 | tHD_WP = 1300, // WP to SDA hold time
649 | tBUF = 500; // Bus free time
650 | `endif
651 | `endif
652 |
653 | $width (posedge SCL, tHI);
654 | $width (negedge SCL, tLO);
655 |
656 | $width (posedge SDA &&& SCL, tBUF);
657 |
658 | $setup (posedge SCL, negedge SDA &&& TimingCheckEnable, tSU_STA);
659 | $setup (SDA, posedge SCL &&& TimingCheckEnable, tSU_DAT);
660 | $setup (posedge SCL, posedge SDA &&& TimingCheckEnable, tSU_STO);
661 | $setup (WP, posedge tstSTOP &&& TimingCheckEnable, tSU_WP);
662 |
663 | $hold (negedge SDA &&& TimingCheckEnable, negedge SCL, tHD_STA);
664 | $hold (posedge tstSTOP &&& TimingCheckEnable, WP, tHD_WP);
665 | endspecify
666 |
667 | endmodule
668 |
--------------------------------------------------------------------------------
/src/avr_interface.v:
--------------------------------------------------------------------------------
1 | module avr_interface #(
2 | parameter CLK_RATE = 50000000,
3 | parameter SERIAL_BAUD_RATE = 500000
4 | )(
5 | input clk,
6 | input rst,
7 |
8 | // cclk, or configuration clock is used when the FPGA is begin configured.
9 | // The AVR will hold cclk high when it has finished initializing.
10 | // It is important not to drive the lines connecting to the AVR
11 | // until cclk is high for a short period of time to avoid contention.
12 | input cclk,
13 |
14 | // AVR SPI Signals
15 | output spi_miso,
16 | input spi_mosi,
17 | input spi_sck,
18 | input spi_ss,
19 | output [3:0] spi_channel,
20 |
21 | // AVR Serial Signals
22 | output tx,
23 | input rx,
24 |
25 | // ADC Interface Signals
26 | input [3:0] channel,
27 | output new_sample,
28 | output [9:0] sample,
29 | output [3:0] sample_channel,
30 |
31 | // Serial TX User Interface
32 | input [7:0] tx_data,
33 | input new_tx_data,
34 | output tx_busy,
35 | input tx_block,
36 |
37 | // Serial Rx User Interface
38 | output [7:0] rx_data,
39 | output new_rx_data
40 | );
41 |
42 | wire ready;
43 | wire n_rdy = !ready;
44 | wire spi_done;
45 | wire [7:0] spi_dout;
46 |
47 | wire tx_m;
48 | wire spi_miso_m;
49 |
50 | reg byte_ct_d, byte_ct_q;
51 | reg [9:0] sample_d, sample_q;
52 | reg new_sample_d, new_sample_q;
53 | reg [3:0] sample_channel_d, sample_channel_q;
54 | reg [3:0] block_d, block_q;
55 | reg busy_d, busy_q;
56 |
57 | // cclk_detector is used to detect when cclk is high signaling when
58 | // the AVR is ready
59 | cclk_detector #(.CLK_RATE(CLK_RATE)) cclk_detector (
60 | .clk(clk),
61 | .rst(rst),
62 | .cclk(cclk),
63 | .ready(ready)
64 | );
65 |
66 | spi_slave spi_slave (
67 | .clk(clk),
68 | .rst(n_rdy),
69 | .ss(spi_ss),
70 | .mosi(spi_mosi),
71 | .miso(spi_miso_m),
72 | .sck(spi_sck),
73 | .done(spi_done),
74 | .din(8'hff),
75 | .dout(spi_dout)
76 | );
77 |
78 | // CLK_PER_BIT is the number of cycles each 'bit' lasts for
79 | // rtoi converts a 'real' number to an 'integer'
80 | parameter CLK_PER_BIT = $rtoi($ceil(CLK_RATE/SERIAL_BAUD_RATE));
81 |
82 | serial_rx #(.CLK_PER_BIT(CLK_PER_BIT)) serial_rx (
83 | .clk(clk),
84 | .rst(n_rdy),
85 | .rx(rx),
86 | .data(rx_data),
87 | .new_data(new_rx_data)
88 | );
89 |
90 | serial_tx #(.CLK_PER_BIT(CLK_PER_BIT)) serial_tx (
91 | .clk(clk),
92 | .rst(n_rdy),
93 | .tx(tx_m),
94 | .block(busy_q),
95 | .busy(tx_busy),
96 | .data(tx_data),
97 | .new_data(new_tx_data)
98 | );
99 |
100 | // Output declarations
101 | assign new_sample = new_sample_q;
102 | assign sample = sample_q;
103 | assign sample_channel = sample_channel_q;
104 |
105 | // these signals connect to the AVR and should be Z when the AVR isn't ready
106 | assign spi_channel = ready ? channel : 4'bZZZZ;
107 | assign spi_miso = ready && !spi_ss ? spi_miso_m : 1'bZ;
108 | assign tx = ready ? tx_m : 1'bZ;
109 |
110 | always @(*) begin
111 | byte_ct_d = byte_ct_q;
112 | sample_d = sample_q;
113 | new_sample_d = 1'b0;
114 | sample_channel_d = sample_channel_q;
115 |
116 | busy_d = busy_q;
117 | block_d = {block_q[2:0], tx_block};
118 |
119 | if (block_q[3] ^ block_q[2])
120 | busy_d = 1'b0;
121 |
122 | if (!tx_busy && new_tx_data)
123 | busy_d = 1'b1;
124 |
125 | if (spi_ss) begin // device is not selected
126 | byte_ct_d = 1'b0;
127 | end
128 |
129 | if (spi_done) begin // sent/received data from SPI
130 | if (byte_ct_q == 1'b0) begin
131 | sample_d[7:0] = spi_dout; // first byte is the 8 LSB of the sample
132 | byte_ct_d = 1'b1;
133 | end else begin
134 | sample_d[9:8] = spi_dout[1:0]; // second byte is the channel 2 MSB of the sample
135 | sample_channel_d = spi_dout[7:4]; // and the channel that was sampled
136 | byte_ct_d = 1'b1; // slave-select must be brought high before the next transfer
137 | new_sample_d = 1'b1;
138 | end
139 | end
140 | end
141 |
142 | always @(posedge clk) begin
143 | if (n_rdy) begin
144 | byte_ct_q <= 1'b0;
145 | sample_q <= 10'b0;
146 | new_sample_q <= 1'b0;
147 | end else begin
148 | byte_ct_q <= byte_ct_d;
149 | sample_q <= sample_d;
150 | new_sample_q <= new_sample_d;
151 | end
152 |
153 | block_q <= block_d;
154 | busy_q <= busy_d;
155 | sample_channel_q <= sample_channel_d;
156 | end
157 |
158 | endmodule
--------------------------------------------------------------------------------
/src/cclk_detector.v:
--------------------------------------------------------------------------------
1 | module cclk_detector #(
2 | parameter CLK_RATE = 50000000
3 | )(
4 | input clk,
5 | input rst,
6 | input cclk,
7 | output ready
8 | );
9 |
10 | parameter CTR_SIZE = $clog2(CLK_RATE/50000);
11 |
12 | reg [CTR_SIZE-1:0] ctr_d, ctr_q;
13 | reg ready_d, ready_q;
14 |
15 | assign ready = ready_q;
16 |
17 | // ready should only go high once cclk has been high for a while
18 | // if cclk ever falls, ready should go low again
19 | always @(ctr_q or cclk) begin
20 | ready_d = 1'b0;
21 | if (cclk == 1'b0) begin // when cclk is 0 reset the counter
22 | ctr_d = 1'b0;
23 | end else if (ctr_q != {CTR_SIZE{1'b1}}) begin
24 | ctr_d = ctr_q + 1'b1; // counter isn't max value yet
25 | end else begin
26 | ctr_d = ctr_q;
27 | ready_d = 1'b1; // counter reached the max, we are ready
28 | end
29 |
30 | end
31 |
32 | always @(posedge clk) begin
33 | if (rst) begin
34 | ctr_q <= 1'b0;
35 | ready_q <= 1'b0;
36 | end else begin
37 | ctr_q <= ctr_d;
38 | ready_q <= ready_d;
39 | end
40 | end
41 | endmodule
42 |
--------------------------------------------------------------------------------
/src/mojo.ucf:
--------------------------------------------------------------------------------
1 | #Created by Constraints Editor (xc6slx9-tqg144-3) - 2012/11/05
2 | NET "clk" TNM_NET = clk;
3 | TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50%;
4 |
5 | # PlanAhead Generated physical constraints
6 | NET "clk" LOC = P56 | IOSTANDARD = LVTTL;
7 | NET "rst_n" LOC = P38 | IOSTANDARD = LVTTL;
8 |
9 | NET "cclk" LOC = P70 | IOSTANDARD = LVTTL;
10 |
11 | NET "led<0>" LOC = P134 | IOSTANDARD = LVTTL;
12 | NET "led<1>" LOC = P133 | IOSTANDARD = LVTTL;
13 | NET "led<2>" LOC = P132 | IOSTANDARD = LVTTL;
14 | NET "led<3>" LOC = P131 | IOSTANDARD = LVTTL;
15 | NET "led<4>" LOC = P127 | IOSTANDARD = LVTTL;
16 | NET "led<5>" LOC = P126 | IOSTANDARD = LVTTL;
17 | NET "led<6>" LOC = P124 | IOSTANDARD = LVTTL;
18 | NET "led<7>" LOC = P123 | IOSTANDARD = LVTTL;
19 |
20 | NET "spi_mosi" LOC = P44 | IOSTANDARD = LVTTL;
21 | NET "spi_miso" LOC = P45 | IOSTANDARD = LVTTL;
22 | NET "spi_ss" LOC = P48 | IOSTANDARD = LVTTL;
23 | NET "spi_sck" LOC = P43 | IOSTANDARD = LVTTL;
24 | NET "spi_channel<0>" LOC = P46 | IOSTANDARD = LVTTL;
25 | NET "spi_channel<1>" LOC = P61 | IOSTANDARD = LVTTL;
26 | NET "spi_channel<2>" LOC = P62 | IOSTANDARD = LVTTL;
27 | NET "spi_channel<3>" LOC = P65 | IOSTANDARD = LVTTL;
28 |
29 | NET "avr_tx" LOC = P55 | IOSTANDARD = LVTTL;
30 | NET "avr_rx" LOC = P59 | IOSTANDARD = LVTTL;
31 | NET "avr_rx_busy" LOC = P39 | IOSTANDARD = LVTTL;
32 |
33 | NET "i2c_sda" LOC = P57 | IOSTANDARD = LVTTL;
34 | NET "i2c_scl" LOC = P66 | IOSTANDARD = LVTTL;
35 | NET "i2c_clk_in" LOC = P74 | IOSTANDARD = LVTTL;
36 |
37 |
--------------------------------------------------------------------------------
/src/mojo_top.v:
--------------------------------------------------------------------------------
1 | module mojo_top(
2 | // 50MHz clock input
3 | input wire clk,
4 | // Input from reset button (active low)
5 | input wire rst_n,
6 | // cclk input from AVR, high when AVR is ready
7 | input wire cclk,
8 | // Outputs to the 8 onboard LEDs
9 | output wire [7:0]led,
10 | // AVR SPI connections
11 | output wire spi_miso,
12 | input wire spi_ss,
13 | input wire spi_mosi,
14 | input wire spi_sck,
15 | // AVR ADC channel select
16 | output wire [3:0] spi_channel,
17 | // Serial connections
18 | input wire avr_tx, // AVR Tx => FPGA Rx
19 | output wire avr_rx, // AVR Rx => FPGA Tx
20 | input wire avr_rx_busy, // AVR Rx buffer full
21 |
22 | output wire i2c_scl,
23 | inout wire i2c_sda,
24 |
25 | output wire i2c_clk_in
26 | );
27 |
28 | wire reset = ~rst_n; // make reset active high
29 |
30 | // these signals should be high-z when not used
31 | assign spi_miso = 1'bz;
32 | assign avr_rx = 1'bz;
33 | assign spi_channel = 4'bzzzz;
34 |
35 | assign led[5:0] = led_buffer;
36 | assign led[7] = tick_1s;
37 | assign led[6] = i2c_clk_in;
38 |
39 | wire tick_1s;
40 |
41 | //Generate a 1s timer
42 | //timer #(.CTR_LEN(26)) second_timer (
43 | timer #(.CTR_LEN(16)) second_timer (
44 | .clk(clk),
45 | .reset(reset),
46 | .tick(tick_1s)
47 | );
48 |
49 |
50 | clk_divider #(.DIVIDER(500)) i2c_clk_divider (
51 | .reset(reset),
52 | .clk_in(clk),
53 | .clk_out(i2c_clk_in)
54 | );
55 |
56 | wire i2c_start;
57 | reg i2c_reset = 1'b1;
58 | wire [7:0] i2c_nbytes;
59 | wire [6:0] i2c_slave_addr;
60 | wire i2c_rw;
61 | wire [7:0] i2c_write_data;
62 | wire [7:0] i2c_read_data;
63 | wire i2c_tx_data_req;
64 | wire i2c_rx_data_ready;
65 | wire ready;
66 | wire busy;
67 |
68 | i2c_master i2c (
69 | .clk(i2c_clk_in),
70 | .reset(i2c_reset),
71 | .start(i2c_start),
72 | .nbytes_in(i2c_nbytes),
73 | .addr_in(i2c_slave_addr),
74 | .rw_in(i2c_rw),
75 | .write_data(i2c_write_data),
76 | .read_data(i2c_read_data),
77 | .tx_data_req(i2c_tx_data_req),
78 | .rx_data_ready(i2c_rx_data_ready),
79 | .sda_w(i2c_sda),
80 | .scl(i2c_scl)
81 | );
82 |
83 | wire [6:0] slave_addr = 7'b1010000;
84 | reg [15:0] mem_addr;
85 | wire [7:0] read_n_bytes = 8'd1;
86 |
87 | wire [7:0] read_nbytes = 1;
88 | reg start = 0;
89 | wire [7:0] data_out;
90 | wire byte_ready;
91 | wire eeprom_busy;
92 |
93 | read_eeprom instance_name (
94 | .clk(clk),
95 | .reset(reset),
96 | .slave_addr_w(slave_addr),
97 | .mem_addr_w(mem_addr),
98 | .read_nbytes_w(read_nbytes),
99 | .start(start),
100 | .data_out(data_out),
101 | .byte_ready(byte_ready),
102 | .i2c_slave_addr(i2c_slave_addr),
103 | .i2c_rw(i2c_rw),
104 | .i2c_write_data(i2c_write_data),
105 | .i2c_nbytes(i2c_nbytes),
106 | .i2c_read_data(i2c_read_data),
107 | .i2c_tx_data_req(i2c_tx_data_req),
108 | .i2c_rx_data_ready(i2c_rx_data_ready),
109 | .i2c_start(i2c_start),
110 | .busy(eeprom_busy)
111 | );
112 |
113 | reg [5:0] led_buffer;
114 |
115 | //every time a new byte is ready, write it to the LEDs
116 | always @(posedge byte_ready) begin
117 | led_buffer <= data_out[5:0];
118 | end
119 |
120 |
121 | reg measured_this_pulse;
122 |
123 | always @(posedge clk) begin
124 | if (reset == 1) begin
125 | mem_addr <= 16'h0000;
126 | measured_this_pulse <= 0;
127 |
128 | end else begin
129 |
130 | if ((tick_1s == 1) && (measured_this_pulse == 0)) begin
131 | measured_this_pulse <= 1;
132 | mem_addr <= mem_addr + 1'b1;
133 | if (mem_addr > 8) begin
134 | mem_addr <= 0;
135 | end
136 | start <= 1;
137 | end //tick_1s==1
138 |
139 | if ((start == 1) && (eeprom_busy == 1)) begin
140 | start <= 0;
141 | end //eeprom_busy and start
142 |
143 | if (tick_1s == 0) begin
144 | measured_this_pulse <= 0;
145 | end //tick_1s==0
146 |
147 | end //reset
148 | end
149 |
150 |
151 | //we need to make sure the i2c module is reset *after*
152 | //it's clock has begun
153 | always @(negedge i2c_clk_in) begin
154 |
155 | if (reset == 1) begin
156 | i2c_reset <= 1;
157 | end else begin
158 | i2c_reset <= 0;
159 | end
160 | end //posedge clk_i2c_in
161 |
162 |
163 |
164 |
165 |
166 | endmodule
--------------------------------------------------------------------------------
/src/serial_rx.v:
--------------------------------------------------------------------------------
1 | module serial_rx #(
2 | parameter CLK_PER_BIT = 50
3 | )(
4 | input clk,
5 | input rst,
6 | input rx,
7 | output [7:0] data,
8 | output new_data
9 | );
10 |
11 | // clog2 is 'ceiling of log base 2' which gives you the number of bits needed to store a value
12 | parameter CTR_SIZE = $clog2(CLK_PER_BIT);
13 |
14 | localparam STATE_SIZE = 2;
15 | localparam IDLE = 2'd0,
16 | WAIT_HALF = 2'd1,
17 | WAIT_FULL = 2'd2,
18 | WAIT_HIGH = 2'd3;
19 |
20 | reg [CTR_SIZE-1:0] ctr_d, ctr_q;
21 | reg [2:0] bit_ctr_d, bit_ctr_q;
22 | reg [7:0] data_d, data_q;
23 | reg new_data_d, new_data_q;
24 | reg [STATE_SIZE-1:0] state_d, state_q = IDLE;
25 | reg rx_d, rx_q;
26 |
27 | assign new_data = new_data_q;
28 | assign data = data_q;
29 |
30 | always @(*) begin
31 | rx_d = rx;
32 | state_d = state_q;
33 | ctr_d = ctr_q;
34 | bit_ctr_d = bit_ctr_q;
35 | data_d = data_q;
36 | new_data_d = 1'b0;
37 |
38 | case (state_q)
39 | IDLE: begin
40 | bit_ctr_d = 3'b0;
41 | ctr_d = 1'b0;
42 | if (rx_q == 1'b0) begin
43 | state_d = WAIT_HALF;
44 | end
45 | end
46 | WAIT_HALF: begin
47 | ctr_d = ctr_q + 1'b1;
48 | if (ctr_q == (CLK_PER_BIT >> 1)) begin
49 | ctr_d = 1'b0;
50 | state_d = WAIT_FULL;
51 | end
52 | end
53 | WAIT_FULL: begin
54 | ctr_d = ctr_q + 1'b1;
55 | if (ctr_q == CLK_PER_BIT - 1) begin
56 | data_d = {rx_q, data_q[7:1]};
57 | bit_ctr_d = bit_ctr_q + 1'b1;
58 | ctr_d = 1'b0;
59 | if (bit_ctr_q == 3'd7) begin
60 | state_d = WAIT_HIGH;
61 | new_data_d = 1'b1;
62 | end
63 | end
64 | end
65 | WAIT_HIGH: begin
66 | if (rx_q == 1'b1) begin
67 | state_d = IDLE;
68 | end
69 | end
70 | default: begin
71 | state_d = IDLE;
72 | end
73 | endcase
74 |
75 | end
76 |
77 | always @(posedge clk) begin
78 | if (rst) begin
79 | ctr_q <= 1'b0;
80 | bit_ctr_q <= 3'b0;
81 | new_data_q <= 1'b0;
82 | state_q <= IDLE;
83 | end else begin
84 | ctr_q <= ctr_d;
85 | bit_ctr_q <= bit_ctr_d;
86 | new_data_q <= new_data_d;
87 | state_q <= state_d;
88 | end
89 |
90 | rx_q <= rx_d;
91 | data_q <= data_d;
92 | end
93 |
94 | endmodule
--------------------------------------------------------------------------------
/src/serial_tx.v:
--------------------------------------------------------------------------------
1 | module serial_tx #(
2 | parameter CLK_PER_BIT = 50
3 | )(
4 | input clk,
5 | input rst,
6 | output tx,
7 | input block,
8 | output busy,
9 | input [7:0] data,
10 | input new_data
11 | );
12 |
13 | // clog2 is 'ceiling of log base 2' which gives you the number of bits needed to store a value
14 | parameter CTR_SIZE = $clog2(CLK_PER_BIT);
15 |
16 | localparam STATE_SIZE = 2;
17 | localparam IDLE = 2'd0,
18 | START_BIT = 2'd1,
19 | DATA = 2'd2,
20 | STOP_BIT = 2'd3;
21 |
22 | reg [CTR_SIZE-1:0] ctr_d, ctr_q;
23 | reg [2:0] bit_ctr_d, bit_ctr_q;
24 | reg [7:0] data_d, data_q;
25 | reg [STATE_SIZE-1:0] state_d, state_q = IDLE;
26 | reg tx_d, tx_q;
27 | reg busy_d, busy_q;
28 | reg block_d, block_q;
29 |
30 | assign tx = tx_q;
31 | assign busy = busy_q;
32 |
33 | always @(*) begin
34 | block_d = block;
35 | ctr_d = ctr_q;
36 | bit_ctr_d = bit_ctr_q;
37 | data_d = data_q;
38 | state_d = state_q;
39 | busy_d = busy_q;
40 |
41 | case (state_q)
42 | IDLE: begin
43 | if (block_q) begin
44 | busy_d = 1'b1;
45 | tx_d = 1'b1;
46 | end else begin
47 | busy_d = 1'b0;
48 | tx_d = 1'b1;
49 | bit_ctr_d = 3'b0;
50 | ctr_d = 1'b0;
51 | if (new_data) begin
52 | data_d = data;
53 | state_d = START_BIT;
54 | busy_d = 1'b1;
55 | end
56 | end
57 | end
58 | START_BIT: begin
59 | busy_d = 1'b1;
60 | ctr_d = ctr_q + 1'b1;
61 | tx_d = 1'b0;
62 | if (ctr_q == CLK_PER_BIT - 1) begin
63 | ctr_d = 1'b0;
64 | state_d = DATA;
65 | end
66 | end
67 | DATA: begin
68 | busy_d = 1'b1;
69 | tx_d = data_q[bit_ctr_q];
70 | ctr_d = ctr_q + 1'b1;
71 | if (ctr_q == CLK_PER_BIT - 1) begin
72 | ctr_d = 1'b0;
73 | bit_ctr_d = bit_ctr_q + 1'b1;
74 | if (bit_ctr_q == 7) begin
75 | state_d = STOP_BIT;
76 | end
77 | end
78 | end
79 | STOP_BIT: begin
80 | busy_d = 1'b1;
81 | tx_d = 1'b1;
82 | ctr_d = ctr_q + 1'b1;
83 | if (ctr_q == CLK_PER_BIT - 1) begin
84 | state_d = IDLE;
85 | end
86 | end
87 | default: begin
88 | state_d = IDLE;
89 | end
90 | endcase
91 | end
92 |
93 | always @(posedge clk) begin
94 | if (rst) begin
95 | state_q <= IDLE;
96 | tx_q <= 1'b1;
97 | end else begin
98 | state_q <= state_d;
99 | tx_q <= tx_d;
100 | end
101 |
102 | block_q <= block_d;
103 | data_q <= data_d;
104 | bit_ctr_q <= bit_ctr_d;
105 | ctr_q <= ctr_d;
106 | busy_q <= busy_d;
107 | end
108 |
109 | endmodule
--------------------------------------------------------------------------------
/src/spi_slave.v:
--------------------------------------------------------------------------------
1 | module spi_slave(
2 | input clk,
3 | input rst,
4 | input ss,
5 | input mosi,
6 | output miso,
7 | input sck,
8 | output done,
9 | input [7:0] din,
10 | output [7:0] dout
11 | );
12 |
13 | reg mosi_d, mosi_q;
14 | reg ss_d, ss_q;
15 | reg sck_d, sck_q;
16 | reg sck_old_d, sck_old_q;
17 | reg [7:0] data_d, data_q;
18 | reg done_d, done_q;
19 | reg [2:0] bit_ct_d, bit_ct_q;
20 | reg [7:0] dout_d, dout_q;
21 | reg miso_d, miso_q;
22 |
23 | assign miso = miso_q;
24 | assign done = done_q;
25 | assign dout = dout_q;
26 |
27 | always @(*) begin
28 | ss_d = ss;
29 | mosi_d = mosi;
30 | miso_d = miso_q;
31 | sck_d = sck;
32 | sck_old_d = sck_q;
33 | data_d = data_q;
34 | done_d = 1'b0;
35 | bit_ct_d = bit_ct_q;
36 | dout_d = dout_q;
37 |
38 | if (ss_q) begin
39 | bit_ct_d = 3'b0;
40 | data_d = din;
41 | miso_d = data_q[7];
42 | end else begin
43 | if (!sck_old_q && sck_q) begin // rising edge
44 | data_d = {data_q[6:0], mosi_q};
45 | bit_ct_d = bit_ct_q + 1'b1;
46 | if (bit_ct_q == 3'b111) begin
47 | dout_d = {data_q[6:0], mosi_q};
48 | done_d = 1'b1;
49 | data_d = din;
50 | end
51 | end else if (sck_old_q && !sck_q) begin // falling edge
52 | miso_d = data_q[7];
53 | end
54 | end
55 | end
56 |
57 | always @(posedge clk) begin
58 | if (rst) begin
59 | done_q <= 1'b0;
60 | bit_ct_q <= 3'b0;
61 | dout_q <= 8'b0;
62 | miso_q <= 1'b1;
63 | end else begin
64 | done_q <= done_d;
65 | bit_ct_q <= bit_ct_d;
66 | dout_q <= dout_d;
67 | miso_q <= miso_d;
68 | end
69 |
70 | sck_q <= sck_d;
71 | mosi_q <= mosi_d;
72 | ss_q <= ss_d;
73 | data_q <= data_d;
74 | sck_old_q <= sck_old_d;
75 |
76 | end
77 |
78 |
79 | endmodule
80 |
--------------------------------------------------------------------------------
/syn/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/testbench.v:
--------------------------------------------------------------------------------
1 | `timescale 10ns / 1ps
2 |
3 | ////////////////////////////////////////////////////////////////////////////////
4 | // Company:
5 | // Engineer:
6 | //
7 | // Create Date: 00:28:21 02/28/2016
8 | // Design Name: i2c_master_v4
9 | // Module Name: C:/Users/matt/Documents/mojo/i2c_master/test_i2c_master_v4.v
10 | // Project Name: i2c_master
11 | // Target Device:
12 | // Tool versions:
13 | // Description:
14 | //
15 | // Verilog Test Fixture created by ISE for module: i2c_master_v4
16 | //
17 | // Dependencies:
18 | //
19 | // Revision:
20 | // Revision 0.01 - File Created
21 | // Additional Comments:
22 | //
23 | ////////////////////////////////////////////////////////////////////////////////
24 |
25 | module testbench;
26 |
27 | // Inputs
28 | reg clk;
29 | reg reset;
30 | reg i2c_reset;
31 | reg [15:0] mem_addr;
32 | reg [6:0] slave_addr;
33 | reg [7:0] read_nbytes;
34 | reg data_ready;
35 |
36 | reg start;
37 |
38 |
39 | // Outputs
40 | wire scl;
41 | wire [7:0] data_out;
42 |
43 |
44 | // Bidirs
45 | wire sda_w;
46 |
47 |
48 | wire i2c_clk;
49 | wire [7:0] i2c_nbytes;
50 | wire [6:0] i2c_slave_addr;
51 | wire i2c_rw;
52 | wire [7:0] i2c_write_data;
53 | wire [7:0] i2c_read_data;
54 | wire i2c_tx_data_req;
55 | wire i2c_rx_data_ready;
56 | wire i2c_start;
57 |
58 | wire byte_ready;
59 |
60 |
61 |
62 | // Instantiate the Unit Under Test (UUT)
63 | i2c_master uut2 (
64 | .clk(i2c_clk),
65 | .reset(i2c_reset),
66 | .start(i2c_start),
67 | .nbytes_in(i2c_nbytes),
68 | .addr_in(i2c_slave_addr),
69 | .rw_in(i2c_rw),
70 | .write_data(i2c_write_data),
71 | .read_data(i2c_read_data),
72 | .tx_data_req(i2c_tx_data_req),
73 | .rx_data_ready(i2c_rx_data_ready),
74 | .sda_w(sda_w),
75 | .scl(scl)
76 | );
77 |
78 |
79 | clk_divider #(.DIVIDER(500)) i2c_clk_divider (
80 | .reset(reset),
81 | .clk_in(clk),
82 | .clk_out(i2c_clk)
83 | );
84 |
85 | read_eeprom uut (
86 | .clk(clk),
87 | .reset(reset),
88 | .slave_addr_w(slave_addr),
89 | .mem_addr_w(mem_addr),
90 | .read_nbytes_w(read_nbytes),
91 | .start(start),
92 | .i2c_slave_addr(i2c_slave_addr),
93 | .i2c_rw(i2c_rw),
94 | .i2c_write_data(i2c_write_data),
95 | .i2c_nbytes(i2c_nbytes),
96 | .i2c_read_data(i2c_read_data),
97 | .i2c_tx_data_req(i2c_tx_data_req),
98 | .i2c_rx_data_ready(i2c_rx_data_ready),
99 | .i2c_start(i2c_start),
100 | .data_out(data_out),
101 | .byte_ready(byte_ready)
102 | );
103 |
104 |
105 | initial begin
106 | // Initialize Inputs
107 | clk = 0;
108 | forever begin
109 | clk = #1 ~clk;
110 | end
111 | end
112 |
113 | initial begin
114 | // Initialize Inputs
115 | reset = 1;
116 | i2c_reset = 1;
117 |
118 | // Wait 100 ns for global reset to finish
119 | #5000;
120 | //start up the clocks
121 | reset = 0;
122 | #5000;
123 |
124 | // Add stimulus here
125 | i2c_reset = 0;
126 | slave_addr = 8'haa;
127 | mem_addr = 16'hF0F0;
128 | read_nbytes = 2;
129 |
130 | #10000;
131 |
132 | //set the start bit
133 | start = 1;
134 |
135 |
136 | #10000
137 | start = 0;
138 | #100000;
139 |
140 |
141 | $finish;
142 |
143 | end
144 |
145 | endmodule
146 |
147 |
--------------------------------------------------------------------------------
/testbench_mojo_top.v:
--------------------------------------------------------------------------------
1 | `timescale 10ns / 1ps
2 |
3 | ////////////////////////////////////////////////////////////////////////////////
4 | // Company:
5 | // Engineer:
6 | //
7 | // Create Date: 19:54:18 03/09/2016
8 | // Design Name: mojo_top
9 | // Module Name: C:/Users/matt/Documents/projects/mojo/i2c-eeprom/testbench_mojo_top.v
10 | // Project Name: Mojo-Base
11 | // Target Device:
12 | // Tool versions:
13 | // Description:
14 | //
15 | // Verilog Test Fixture created by ISE for module: mojo_top
16 | //
17 | // Dependencies:
18 | //
19 | // Revision:
20 | // Revision 0.01 - File Created
21 | // Additional Comments:
22 | //
23 | ////////////////////////////////////////////////////////////////////////////////
24 |
25 | module testbench_mojo_top;
26 |
27 | // Inputs
28 | reg clk;
29 | reg rst_n;
30 | reg cclk;
31 | reg spi_ss;
32 | reg spi_mosi;
33 | reg spi_sck;
34 | reg avr_tx;
35 | reg avr_rx_busy;
36 |
37 | // Outputs
38 | wire [7:0] led;
39 | wire spi_miso;
40 | wire [3:0] spi_channel;
41 | wire avr_rx;
42 | wire i2c_scl;
43 | wire i2c_clk_in;
44 |
45 | // Bidirs
46 | wire i2c_sda;
47 |
48 | // Instantiate the Unit Under Test (UUT)
49 | mojo_top uut (
50 | .clk(clk),
51 | .rst_n(rst_n),
52 | .cclk(cclk),
53 | .led(led),
54 | .spi_miso(spi_miso),
55 | .spi_ss(spi_ss),
56 | .spi_mosi(spi_mosi),
57 | .spi_sck(spi_sck),
58 | .spi_channel(spi_channel),
59 | .avr_tx(avr_tx),
60 | .avr_rx(avr_rx),
61 | .avr_rx_busy(avr_rx_busy),
62 | .i2c_scl(i2c_scl),
63 | .i2c_sda(i2c_sda),
64 | .i2c_clk_in(i2c_clk_in)
65 | );
66 |
67 |
68 | wire A0 = 0;
69 | wire A1 = 0;
70 | wire A2 = 0;
71 | wire WP = 0;
72 | wire reset = ~rst_n;
73 |
74 | M24FC512 eeprom (
75 | .A0(A0),
76 | .A1(A1),
77 | .A2(A2),
78 | .WP(WP),
79 | .SDA(i2c_sda),
80 | .SCL(i2c_scl),
81 | .RESET(reset)
82 | );
83 |
84 | initial begin
85 | // Initialize Inputs
86 | clk = 0;
87 | forever begin
88 | clk = #1 ~clk;
89 | end
90 | end
91 |
92 | initial begin
93 | // Initialize Inputs
94 | rst_n = 0;
95 | cclk = 0;
96 | spi_ss = 0;
97 | spi_mosi = 0;
98 | spi_sck = 0;
99 | avr_tx = 0;
100 | avr_rx_busy = 0;
101 |
102 | // Wait 100 ns for global reset to finish
103 | #100;
104 |
105 | // Add stimulus here
106 | cclk = 1;
107 | rst_n = 1;
108 |
109 | end
110 |
111 | endmodule
112 |
113 |
--------------------------------------------------------------------------------
/timer.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 19:14:34 03/04/2016
7 | // Design Name:
8 | // Module Name: timer
9 | // Project Name:
10 | // Target Devices:
11 | // Tool versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 | module timer #(parameter CTR_LEN = 26) (
22 | input clk,
23 | input reset,
24 | output tick
25 | );
26 |
27 | reg [CTR_LEN-1:0] counter_d, counter_q;
28 |
29 | assign tick = counter_q[CTR_LEN-1];
30 |
31 | always @(counter_q) begin
32 | counter_d = counter_q + 1'b1;
33 | end
34 |
35 | always @(posedge clk) begin
36 | if (reset) begin
37 | counter_q <= 25'b0;
38 | end else begin
39 | counter_q <= counter_d;
40 | end
41 | end
42 | endmodule
43 |
44 |
--------------------------------------------------------------------------------