source: trunk/MultiChannelUSB/control.v@ 136

Last change on this file since 136 was 91, checked in by demin, 15 years ago

fix communication with external SRAM

File size: 4.2 KB
Line 
1module control
2 (
3 input wire clock, reset,
4
5 input wire rx_empty, tx_full,
6 input wire [7:0] rx_data,
7
8 output wire rx_rdreq, tx_wrreq,
9 output wire [7:0] tx_data,
10
11 output wire bus_wren,
12 output wire [31:0] bus_addr,
13 output wire [15:0] bus_mosi,
14
15 input wire [15:0] bus_miso,
16 input wire bus_busy,
17
18 output wire led
19 );
20
21 reg [23:0] led_counter;
22
23 reg int_bus_wren;
24 reg [31:0] int_bus_addr;
25 reg [31:0] int_bus_cntr;
26 reg [15:0] int_bus_mosi;
27
28 reg int_rdreq, int_wrreq;
29 reg [7:0] int_data;
30 reg int_led;
31
32 reg [1:0] byte_counter;
33 reg [4:0] idle_counter;
34
35 reg [4:0] state;
36
37 reg [31:0] address, counter;
38
39 reg [15:0] prefix;
40
41 wire [15:0] dest, data;
42
43 reg [7:0] buffer [3:0];
44
45 assign dest = {buffer[0], buffer[1]};
46 assign data = {buffer[2], buffer[3]};
47
48 always @(posedge clock)
49 begin
50 if (~rx_empty)
51 begin
52 int_led <= 1'b0;
53 led_counter <= 24'd0;
54 end
55 else
56 begin
57 if (&led_counter)
58 begin
59 int_led <= 1'b1;
60 end
61 else
62 begin
63 led_counter <= led_counter + 24'd1;
64 end
65 end
66
67 case(state)
68 0:
69 begin
70 int_rdreq <= 1'b1;
71 int_wrreq <= 1'b0;
72 idle_counter <= 5'd0;
73 byte_counter <= 2'd0;
74 state <= 5'd1;
75 end
76
77 1:
78 begin
79 // read 4 bytes
80 if (~rx_empty)
81 begin
82 idle_counter <= 5'd0;
83 byte_counter <= byte_counter + 2'd1;
84 buffer[byte_counter] <= rx_data;
85 if (&byte_counter)
86 begin
87 int_rdreq <= 1'b0;
88 state <= 5'd2;
89 end
90 end
91 else if(|byte_counter)
92 begin
93 idle_counter <= idle_counter + 5'd1;
94 if (&idle_counter)
95 begin
96 int_rdreq <= 1'b0;
97 state <= 5'd0;
98 end
99 end
100 end
101
102 2:
103 begin
104 case (dest)
105 16'h0000:
106 begin
107 // reset
108 prefix <= 16'd0;
109 state <= 5'd0;
110 end
111
112
113 16'h0001:
114 begin
115 // prefix register
116 prefix <= data;
117 state <= 5'd0;
118 end
119
120
121 16'h0002:
122 begin
123 // address register
124 address <= {prefix, data};
125 prefix <= 16'd0;
126 state <= 5'd0;
127 end
128
129 16'h0003:
130 begin
131 // counter register
132 counter <= {prefix, data};
133 prefix <= 16'd0;
134 state <= 5'd0;
135 end
136
137 16'h0004:
138 begin
139 // single write
140 int_bus_addr <= address;
141 int_bus_mosi <= data;
142 int_bus_wren <= 1'b1;
143 prefix <= 16'd0;
144 state <= 5'd3;
145 end
146
147 16'h0005:
148 begin
149 // multi read
150 int_bus_addr <= address;
151 int_bus_cntr <= counter;
152 int_bus_wren <= 1'b0;
153 prefix <= 16'd0;
154 state <= 5'd4;
155 end
156
157 default:
158 begin
159 prefix <= 16'd0;
160 state <= 5'd0;
161 end
162 endcase
163 end
164
165 // single write
166 3:
167 begin
168 if (~bus_busy)
169 begin
170 int_bus_addr <= 32'd0;
171 int_bus_mosi <= 16'd0;
172 int_bus_wren <= 1'b0;
173 state <= 5'd0;
174 end
175 end
176
177 // multi read
178 4:
179 begin
180 if (bus_busy)
181 begin
182 buffer[0] <= 8'd1;
183 buffer[1] <= 8'd0;
184 int_bus_cntr <= 32'd0;
185 end
186 else
187 begin
188 buffer[0] <= 8'd0;
189 buffer[1] <= 8'd0;
190 end
191 state <= 5'd7;
192 end
193
194 5:
195 begin
196 buffer[0] <= bus_miso[7:0];
197 buffer[1] <= bus_miso[15:8];
198 int_bus_addr <= int_bus_addr + 32'd1;
199 int_bus_cntr <= int_bus_cntr - 32'd1;
200 state <= 5'd6;
201 end
202
203 6:
204 begin
205 state <= 5'd7;
206 end
207
208 7:
209 begin
210 int_data <= buffer[0];
211 int_wrreq <= 1'b1;
212 state <= 5'd8;
213 end
214
215 8:
216 begin
217 if (~tx_full)
218 begin
219 int_data <= buffer[1];
220 state <= 5'd9;
221 end
222 end
223
224 9:
225 begin
226 if (~tx_full)
227 begin
228 int_wrreq <= 1'b0;
229 state <= 5'd10;
230 end
231 end
232
233 10:
234 begin
235 if (|int_bus_cntr)
236 begin
237 state <= 5'd5;
238 end
239 else
240 begin
241 state <= 5'd0;
242 end
243 end
244
245 default:
246 begin
247 state <= 5'd0;
248 end
249 endcase
250 end
251
252 assign bus_wren = int_bus_wren;
253 assign bus_addr = int_bus_addr;
254 assign bus_mosi = int_bus_mosi;
255 assign rx_rdreq = int_rdreq & (~rx_empty);
256 assign tx_wrreq = int_wrreq & (~tx_full);
257 assign tx_data = int_data;
258 assign led = int_led;
259
260endmodule
Note: See TracBrowser for help on using the repository browser.