source: trunk/MultiChannelUSB/control.v@ 166

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

fix communication with external SRAM

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;
[84]185 end
186 else
187 begin
[91]188 buffer[0] <= 8'd0;
[90]189 buffer[1] <= 8'd0;
[84]190 end
[91]191 state <= 5'd7;
[84]192 end
193
[90]194 5:
[84]195 begin
[90]196 buffer[0] <= bus_miso[7:0];
197 buffer[1] <= bus_miso[15:8];
[91]198 int_bus_addr <= int_bus_addr + 32'd1;
199 int_bus_cntr <= int_bus_cntr - 32'd1;
[90]200 state <= 5'd6;
[84]201 end
202
[90]203 6:
[84]204 begin
[90]205 state <= 5'd7;
[84]206 end
207
[90]208 7:
[84]209 begin
[91]210 int_data <= buffer[0];
211 int_wrreq <= 1'b1;
212 state <= 5'd8;
[84]213 end
214
[90]215 8:
[84]216 begin
[91]217 if (~tx_full)
218 begin
219 int_data <= buffer[1];
220 state <= 5'd9;
221 end
[84]222 end
223
[90]224 9:
[84]225 begin
226 if (~tx_full)
227 begin
228 int_wrreq <= 1'b0;
[91]229 state <= 5'd10;
[84]230 end
231 end
232
[91]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
[59]245 default:
246 begin
[69]247 state <= 5'd0;
[59]248 end
249 endcase
250 end
[90]251
252 assign bus_wren = int_bus_wren;
253 assign bus_addr = int_bus_addr;
254 assign bus_mosi = int_bus_mosi;
[59]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.