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