]>
Commit | Line | Data |
---|---|---|
3b542afc | 1 | `include "master_rom.v" |
ffba35f8 MG |
2 | `include "i2c.v" |
3 | `include "uart.v" | |
3b542afc MG |
4 | |
5 | `ifdef SIM | |
6 | `define UART_DIVIDE 1 | |
7 | `else | |
8 | `define UART_DIVIDE 1 | |
9 | // s/192/3/ for 19200 baud uart | |
10 | `endif | |
11 | ||
ffba35f8 MG |
12 | module master(input CLKin, output [4:0] led, output uart_tx, input uart_rx, output reg ready_out = 1, input ready_in, output scl, output sda); |
13 | // wire clk; | |
14 | // wire clk_tmp; | |
3b542afc MG |
15 | |
16 | //pll pll (.clock_in(CLKin), .clock_out(clk)); | |
17 | ||
18 | reg [20:0] counter = 0; | |
19 | ||
ffba35f8 MG |
20 | `ifdef SIM |
21 | wire clk = CLKin; | |
22 | `else | |
3b542afc MG |
23 | reg clk = 0; |
24 | ||
25 | always @ (posedge CLKin) begin | |
26 | if(counter == 5000) begin | |
27 | counter <= 0; | |
28 | clk <= 1 - clk; | |
29 | end | |
30 | else | |
31 | counter <= counter + 1; | |
32 | end | |
ffba35f8 | 33 | `endif |
3b542afc | 34 | |
7f1b6bd9 MG |
35 | reg [3:0] program_counter = 0; |
36 | wire [31:0] rom_output; | |
3b542afc MG |
37 | |
38 | master_rom master_rom (.clk(clk), .addr(program_counter), .data(rom_output)); | |
39 | ||
ffba35f8 MG |
40 | reg [7:0] i2c_tx_byte; |
41 | reg i2c_transmit = 0; | |
42 | wire i2c_is_transmitting; | |
43 | ||
44 | i2c_write i2c (.clk(clk), .scl(scl), .sda(sda), .tx_byte(i2c_tx_byte), .transmit(i2c_transmit), .is_transmitting(i2c_is_transmitting)); | |
45 | ||
46 | reg [3:0] i2c_init_step = 0; | |
47 | ||
48 | always @ (posedge clk) begin | |
49 | if(i2c_is_transmitting || i2c_transmit) | |
50 | i2c_transmit <= 0; | |
51 | else begin | |
52 | if(i2c_init_step == 0) begin | |
53 | i2c_tx_byte <= 8'h21; // turn on oscillator | |
54 | i2c_transmit <= 1; | |
55 | i2c_init_step <= 1; | |
56 | end else if(i2c_init_step == 1) begin | |
57 | i2c_tx_byte <= 8'h87; // display on, blink 0.5Hz | |
58 | i2c_transmit <= 1; | |
59 | i2c_init_step <= 2; | |
60 | end else if(i2c_init_step == 2) begin | |
61 | i2c_tx_byte <= 8'hEF; // max brightness | |
62 | i2c_transmit <= 1; | |
63 | i2c_init_step <= 3; | |
64 | end | |
65 | end | |
66 | end | |
67 | ||
3b542afc MG |
68 | |
69 | `define STATE_SEND 0 | |
70 | `define STATE_WAIT_PROPAGATE 1 | |
71 | `define STATE_WAIT_NEWS 2 | |
7f1b6bd9 MG |
72 | `define STATE_PROPAGATE_NEWS 3 |
73 | `define STATE_WASTE_TIME 4 | |
3b542afc MG |
74 | |
75 | reg [5:0] state = `STATE_SEND; | |
76 | reg [5:0] uart_ptr = 0; | |
77 | ||
78 | wire received; | |
79 | wire [7:0] rx_byte; | |
80 | reg transmit = 0; | |
81 | reg [7:0] tx_byte = 0; | |
82 | wire is_receiving; | |
83 | wire is_transmitting; | |
84 | ||
85 | // 19200 (actually 300) baud uart | |
86 | uart #(.CLOCK_DIVIDE(`UART_DIVIDE)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte), .is_receiving(is_receiving), .is_transmitting(is_transmitting)); | |
87 | ||
7f1b6bd9 MG |
88 | reg [15:0] waste_counter = 0; |
89 | ||
90 | reg [7:0] saved_news [3:0]; | |
91 | ||
92 | assign led[4] = state != `STATE_WASTE_TIME; | |
ffba35f8 | 93 | assign led[3:0] = i2c_init_step; |
7f1b6bd9 | 94 | |
3b542afc MG |
95 | always @(posedge clk) begin |
96 | case(state) | |
97 | `STATE_SEND: begin | |
98 | if(transmit) begin | |
99 | transmit <= 0; | |
100 | end else if(uart_ptr == 4) begin | |
101 | program_counter <= program_counter + 1; | |
102 | uart_ptr <= 0; | |
7f1b6bd9 MG |
103 | if(rom_output[26:24] == 6) // `OP_ROUTE |
104 | state <= `STATE_WAIT_NEWS; | |
105 | else | |
106 | state <= `STATE_WAIT_PROPAGATE; | |
3b542afc MG |
107 | end else if(!is_transmitting && ready_in) begin |
108 | tx_byte <= rom_output[uart_ptr * 8 +: 8]; | |
109 | transmit <= 1; | |
110 | uart_ptr <= uart_ptr + 1; | |
111 | end | |
112 | end | |
113 | ||
114 | `STATE_WAIT_PROPAGATE: begin | |
115 | if(received) begin | |
7f1b6bd9 | 116 | state <= `STATE_WASTE_TIME; |
3b542afc MG |
117 | end |
118 | end | |
119 | ||
7f1b6bd9 MG |
120 | `STATE_WASTE_TIME: begin |
121 | if(waste_counter == 100) begin | |
122 | waste_counter <= 0; | |
123 | state <= `STATE_SEND; | |
124 | end else | |
125 | waste_counter <= waste_counter + 1; | |
126 | end | |
127 | ||
3b542afc | 128 | `STATE_WAIT_NEWS: begin |
7f1b6bd9 MG |
129 | /** On a route instruction, we: |
130 | - receive the instruction back | |
131 | - receive the news | |
132 | - propagate the news | |
ffba35f8 | 133 | - go to `STATE_WASTE_TIME |
7f1b6bd9 MG |
134 | */ |
135 | if(uart_ptr == 8) begin | |
136 | state <= `STATE_PROPAGATE_NEWS; | |
137 | uart_ptr <= 0; | |
138 | end else if(received) begin | |
139 | if(uart_ptr[2]) /* uart_ptr >= 4 */ | |
140 | saved_news[uart_ptr[1:0]] <= rx_byte; | |
141 | uart_ptr <= uart_ptr + 1; | |
142 | end | |
143 | end // case: `STATE_WAIT_NEWS | |
3b542afc | 144 | |
7f1b6bd9 MG |
145 | `STATE_PROPAGATE_NEWS: begin |
146 | if(uart_ptr == 4) begin | |
147 | state <= `STATE_WASTE_TIME; | |
148 | uart_ptr <= 0; | |
149 | end else if(!is_transmitting && ready_in) begin | |
150 | tx_byte <= saved_news[uart_ptr]; | |
151 | transmit <= 1; | |
152 | uart_ptr <= uart_ptr + 1; | |
153 | end | |
3b542afc MG |
154 | end |
155 | endcase | |
156 | end | |
157 | ||
158 | endmodule |