source: trunk/MultiChannelUSB/control.v@ 90

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

full rewrite

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 state <= 5'd7;
186 end
187 else
188 begin
189 buffer[0] <= 8'd2;
190 buffer[1] <= 8'd0;
191 state <= 5'd6;
192 end
193 end
194
195 5:
196 begin
197 buffer[0] <= bus_miso[7:0];
198 buffer[1] <= bus_miso[15:8];
199 state <= 5'd6;
200 end
201
202 6:
203 begin
204 int_bus_addr <= int_bus_addr + 32'd1;
205 state <= 5'd7;
206 end
207
208 7:
209 begin
210 if (~tx_full)
211 begin
212 int_data <= buffer[0];
213 int_wrreq <= 1'b1;
214 state <= 5'd8;
215 end
216 end
217
218 8:
219 begin
220 int_data <= buffer[1];
221 state <= 5'd9;
222 end
223
224 9:
225 begin
226 if (~tx_full)
227 begin
228 int_wrreq <= 1'b0;
229 if (|int_bus_cntr)
230 begin
231 state <= 5'd5;
232 int_bus_cntr <= int_bus_cntr - 32'd1;
233 end
234 else
235 begin
236 state <= 5'd0;
237 end
238 end
239 end
240
241 default:
242 begin
243 state <= 5'd0;
244 end
245 endcase
246 end
247
248 assign bus_wren = int_bus_wren;
249 assign bus_addr = int_bus_addr;
250 assign bus_mosi = int_bus_mosi;
251 assign rx_rdreq = int_rdreq & (~rx_empty);
252 assign tx_wrreq = int_wrreq & (~tx_full);
253 assign tx_data = int_data;
254 assign led = int_led;
255
256endmodule
Note: See TracBrowser for help on using the repository browser.