1 |
35 |
ns32kum |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
2 |
|
|
//
|
3 |
|
|
// Version: 0.1
|
4 |
|
|
// Date: 2 December 2018
|
5 |
|
|
//
|
6 |
|
|
// Modules contained in this file:
|
7 |
|
|
// 1. DRAM_MOD DRAM Model
|
8 |
|
|
// 2. MAINDEC Main Decoder
|
9 |
|
|
// 3. UART Universal Asynchronous Receiver & Transmitter
|
10 |
|
|
// 4. SRAM External SRAM Interface
|
11 |
|
|
// 5. TRIPUTER Top level of FPGA
|
12 |
|
|
//
|
13 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
14 |
|
|
|
15 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
16 |
|
|
//
|
17 |
|
|
// 1. DRAM_MOD DRAM Model
|
18 |
|
|
//
|
19 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
20 |
|
|
module DRAM_MOD ( MCLK, RST_N, IC_ACC, IDRAM_ADR, DC_ACC, DC_WR, DRAM_ADR, DRAM_DI,
|
21 |
|
|
IC_MDONE, DC_MDONE, ENWR, IC_INHIBIT, DC_INHIBIT, MEM_Q );
|
22 |
|
|
|
23 |
|
|
input MCLK;
|
24 |
|
|
input RST_N;
|
25 |
|
|
input IC_ACC;
|
26 |
|
|
input [28:0] IDRAM_ADR;
|
27 |
|
|
input DC_ACC;
|
28 |
|
|
input DC_WR;
|
29 |
|
|
input [28:0] DRAM_ADR;
|
30 |
|
|
input [35:0] DRAM_DI;
|
31 |
|
|
|
32 |
|
|
output reg IC_MDONE;
|
33 |
|
|
output reg DC_MDONE;
|
34 |
|
|
output ENWR;
|
35 |
|
|
output reg IC_INHIBIT;
|
36 |
|
|
output reg DC_INHIBIT;
|
37 |
|
|
|
38 |
|
|
output reg [127:0] MEM_Q;
|
39 |
|
|
|
40 |
|
|
// +++++++++++++++++++ Memories ++++++++++++++++++++
|
41 |
|
|
|
42 |
|
|
parameter addr_msb = 16; // total memory is 128 kB
|
43 |
|
|
|
44 |
|
|
reg [7:0] EDRAM_F [0:2**(addr_msb-3)-1]; // Byte-wide RAM blocks
|
45 |
|
|
reg [7:0] EDRAM_E [0:2**(addr_msb-3)-1];
|
46 |
|
|
reg [7:0] EDRAM_D [0:2**(addr_msb-3)-1];
|
47 |
|
|
reg [7:0] EDRAM_C [0:2**(addr_msb-3)-1];
|
48 |
|
|
reg [7:0] EDRAM_B [0:2**(addr_msb-3)-1];
|
49 |
|
|
reg [7:0] EDRAM_A [0:2**(addr_msb-3)-1];
|
50 |
|
|
reg [7:0] EDRAM_9 [0:2**(addr_msb-3)-1];
|
51 |
|
|
reg [7:0] EDRAM_8 [0:2**(addr_msb-3)-1];
|
52 |
|
|
reg [7:0] EDRAM_7 [0:2**(addr_msb-3)-1];
|
53 |
|
|
reg [7:0] EDRAM_6 [0:2**(addr_msb-3)-1];
|
54 |
|
|
reg [7:0] EDRAM_5 [0:2**(addr_msb-3)-1];
|
55 |
|
|
reg [7:0] EDRAM_4 [0:2**(addr_msb-3)-1];
|
56 |
|
|
reg [7:0] EDRAM_3 [0:2**(addr_msb-3)-1];
|
57 |
|
|
reg [7:0] EDRAM_2 [0:2**(addr_msb-3)-1];
|
58 |
|
|
reg [7:0] EDRAM_1 [0:2**(addr_msb-3)-1];
|
59 |
|
|
reg [7:0] EDRAM_0 [0:2**(addr_msb-3)-1];
|
60 |
|
|
|
61 |
|
|
wire [15:0] wrbyte;
|
62 |
|
|
wire [addr_msb:4] addr;
|
63 |
|
|
wire dc_active;
|
64 |
|
|
|
65 |
|
|
// +++++++++++++++++++++++++ Datapath +++++++++++++++++++
|
66 |
|
|
|
67 |
|
|
assign dc_active = DC_WR | (DC_ACC & ~DC_MDONE);
|
68 |
|
|
|
69 |
|
|
assign addr = dc_active ? DRAM_ADR[addr_msb:4] : IDRAM_ADR[addr_msb:4];
|
70 |
|
|
|
71 |
|
|
always @(posedge MCLK)
|
72 |
|
|
begin
|
73 |
|
|
MEM_Q[127:120] <= EDRAM_F[addr]; // READ on rising edge
|
74 |
|
|
MEM_Q[119:112] <= EDRAM_E[addr];
|
75 |
|
|
MEM_Q[111:104] <= EDRAM_D[addr];
|
76 |
|
|
MEM_Q[103:96] <= EDRAM_C[addr];
|
77 |
|
|
MEM_Q[95:88] <= EDRAM_B[addr];
|
78 |
|
|
MEM_Q[87:80] <= EDRAM_A[addr];
|
79 |
|
|
MEM_Q[79:72] <= EDRAM_9[addr];
|
80 |
|
|
MEM_Q[71:64] <= EDRAM_8[addr];
|
81 |
|
|
MEM_Q[63:56] <= EDRAM_7[addr];
|
82 |
|
|
MEM_Q[55:48] <= EDRAM_6[addr];
|
83 |
|
|
MEM_Q[47:40] <= EDRAM_5[addr];
|
84 |
|
|
MEM_Q[39:32] <= EDRAM_4[addr];
|
85 |
|
|
MEM_Q[31:24] <= EDRAM_3[addr];
|
86 |
|
|
MEM_Q[23:16] <= EDRAM_2[addr];
|
87 |
|
|
MEM_Q[15:8] <= EDRAM_1[addr];
|
88 |
|
|
MEM_Q[7:0] <= EDRAM_0[addr];
|
89 |
|
|
end
|
90 |
|
|
|
91 |
|
|
assign wrbyte[0] = DC_WR & DRAM_DI[32] & (DRAM_ADR[3:2] == 2'b00);
|
92 |
|
|
assign wrbyte[1] = DC_WR & DRAM_DI[33] & (DRAM_ADR[3:2] == 2'b00);
|
93 |
|
|
assign wrbyte[2] = DC_WR & DRAM_DI[34] & (DRAM_ADR[3:2] == 2'b00);
|
94 |
|
|
assign wrbyte[3] = DC_WR & DRAM_DI[35] & (DRAM_ADR[3:2] == 2'b00);
|
95 |
|
|
assign wrbyte[4] = DC_WR & DRAM_DI[32] & (DRAM_ADR[3:2] == 2'b01);
|
96 |
|
|
assign wrbyte[5] = DC_WR & DRAM_DI[33] & (DRAM_ADR[3:2] == 2'b01);
|
97 |
|
|
assign wrbyte[6] = DC_WR & DRAM_DI[34] & (DRAM_ADR[3:2] == 2'b01);
|
98 |
|
|
assign wrbyte[7] = DC_WR & DRAM_DI[35] & (DRAM_ADR[3:2] == 2'b01);
|
99 |
|
|
assign wrbyte[8] = DC_WR & DRAM_DI[32] & (DRAM_ADR[3:2] == 2'b10);
|
100 |
|
|
assign wrbyte[9] = DC_WR & DRAM_DI[33] & (DRAM_ADR[3:2] == 2'b10);
|
101 |
|
|
assign wrbyte[10] = DC_WR & DRAM_DI[34] & (DRAM_ADR[3:2] == 2'b10);
|
102 |
|
|
assign wrbyte[11] = DC_WR & DRAM_DI[35] & (DRAM_ADR[3:2] == 2'b10);
|
103 |
|
|
assign wrbyte[12] = DC_WR & DRAM_DI[32] & (DRAM_ADR[3:2] == 2'b11);
|
104 |
|
|
assign wrbyte[13] = DC_WR & DRAM_DI[33] & (DRAM_ADR[3:2] == 2'b11);
|
105 |
|
|
assign wrbyte[14] = DC_WR & DRAM_DI[34] & (DRAM_ADR[3:2] == 2'b11);
|
106 |
|
|
assign wrbyte[15] = DC_WR & DRAM_DI[35] & (DRAM_ADR[3:2] == 2'b11);
|
107 |
|
|
|
108 |
|
|
always @(posedge MCLK)
|
109 |
|
|
begin
|
110 |
|
|
if (wrbyte[15]) EDRAM_F[addr] <= DRAM_DI[31:24]; // WRITE on rising edge
|
111 |
|
|
if (wrbyte[14]) EDRAM_E[addr] <= DRAM_DI[23:16];
|
112 |
|
|
if (wrbyte[13]) EDRAM_D[addr] <= DRAM_DI[15:8];
|
113 |
|
|
if (wrbyte[12]) EDRAM_C[addr] <= DRAM_DI[7:0];
|
114 |
|
|
if (wrbyte[11]) EDRAM_B[addr] <= DRAM_DI[31:24]; // WRITE on rising edge
|
115 |
|
|
if (wrbyte[10]) EDRAM_A[addr] <= DRAM_DI[23:16];
|
116 |
|
|
if (wrbyte[9]) EDRAM_9[addr] <= DRAM_DI[15:8];
|
117 |
|
|
if (wrbyte[8]) EDRAM_8[addr] <= DRAM_DI[7:0];
|
118 |
|
|
if (wrbyte[7]) EDRAM_7[addr] <= DRAM_DI[31:24]; // WRITE on rising edge
|
119 |
|
|
if (wrbyte[6]) EDRAM_6[addr] <= DRAM_DI[23:16];
|
120 |
|
|
if (wrbyte[5]) EDRAM_5[addr] <= DRAM_DI[15:8];
|
121 |
|
|
if (wrbyte[4]) EDRAM_4[addr] <= DRAM_DI[7:0];
|
122 |
|
|
if (wrbyte[3]) EDRAM_3[addr] <= DRAM_DI[31:24]; // WRITE on rising edge
|
123 |
|
|
if (wrbyte[2]) EDRAM_2[addr] <= DRAM_DI[23:16];
|
124 |
|
|
if (wrbyte[1]) EDRAM_1[addr] <= DRAM_DI[15:8];
|
125 |
|
|
if (wrbyte[0]) EDRAM_0[addr] <= DRAM_DI[7:0];
|
126 |
|
|
end
|
127 |
|
|
|
128 |
|
|
// +++++++++++++++++++++++++ Controllogic +++++++++++++++++++
|
129 |
|
|
|
130 |
|
|
// each access takes one clock cycle inside the DRAM model. Due to the timing requirement of xx_MDONE the read
|
131 |
|
|
// access is pipelined: it will take two clock cycles to serve a cache read request
|
132 |
|
|
|
133 |
|
|
always @(posedge MCLK) DC_MDONE <= DC_ACC & ~DC_MDONE & ~DC_WR;
|
134 |
|
|
|
135 |
|
|
always @(posedge MCLK) IC_MDONE <= IC_ACC & ~IC_MDONE & ~dc_active;
|
136 |
|
|
|
137 |
|
|
always @(posedge MCLK) DC_INHIBIT <= ~DRAM_ADR[1]; // ~USE_CA => INHIBIT
|
138 |
|
|
|
139 |
|
|
always @(posedge MCLK) IC_INHIBIT <= ~IDRAM_ADR[1]; // ~USE_CA => INHIBIT
|
140 |
|
|
|
141 |
|
|
assign ENWR = 1'b1; // always active
|
142 |
|
|
|
143 |
|
|
endmodule
|
144 |
|
|
|
145 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
146 |
|
|
//
|
147 |
|
|
// 2. MAINDEC Main Decoder
|
148 |
|
|
//
|
149 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
150 |
|
|
module MAINDEC
|
151 |
|
|
(BCLK, RST_N, WRITE, READ, STATUS, SRAM_RDY, ADDR, BOOT_Q, SRAM_Q, UART_Q, BE, IO_DI,
|
152 |
|
|
UART_RD, UART_WR, CESRAM, NMI_N, DRD, READY, BRESET, ENDRAM, LEDR, LEDG, HEXL, HEXM, SSW );
|
153 |
|
|
|
154 |
|
|
input BCLK;
|
155 |
|
|
input RST_N;
|
156 |
|
|
input WRITE;
|
157 |
|
|
input READ;
|
158 |
|
|
input [3:0] STATUS;
|
159 |
|
|
input SRAM_RDY;
|
160 |
|
|
input [31:2] ADDR;
|
161 |
|
|
input [31:0] BOOT_Q;
|
162 |
|
|
input [31:0] SRAM_Q;
|
163 |
|
|
input [3:0] BE;
|
164 |
|
|
input [31:0] IO_DI;
|
165 |
|
|
|
166 |
|
|
output UART_RD;
|
167 |
|
|
output [1:0] UART_WR;
|
168 |
|
|
|
169 |
|
|
input [31:0] UART_Q;
|
170 |
|
|
output CESRAM;
|
171 |
|
|
|
172 |
|
|
output reg NMI_N;
|
173 |
|
|
|
174 |
|
|
output [31:0] DRD;
|
175 |
|
|
output reg READY;
|
176 |
|
|
output reg BRESET;
|
177 |
|
|
output reg ENDRAM;
|
178 |
|
|
|
179 |
|
|
input [9:0] SSW;
|
180 |
|
|
|
181 |
|
|
output reg [6:0] HEXL,HEXM;
|
182 |
|
|
output reg [9:0] LEDR;
|
183 |
|
|
output reg [7:0] LEDG;
|
184 |
|
|
|
185 |
|
|
reg [31:0] DRD;
|
186 |
|
|
reg rd_rdy;
|
187 |
|
|
reg [3:0] init_cou;
|
188 |
|
|
reg [25:0] counter;
|
189 |
|
|
reg [9:0] ssw_reg;
|
190 |
|
|
reg nmie;
|
191 |
|
|
|
192 |
|
|
wire wr_leds,wr_coun;
|
193 |
|
|
wire access;
|
194 |
|
|
|
195 |
|
|
assign access = WRITE | READ;
|
196 |
|
|
|
197 |
|
|
assign UART_WR = (WRITE & (ADDR[31:20] == 12'h202)) ? BE[1:0] : 2'd0;
|
198 |
|
|
assign UART_RD = READ & (ADDR[31:20] == 12'h202) & BE[0]; // Read Data Reg. -> Int to 0
|
199 |
|
|
assign CESRAM = access & (ADDR[31:20] == 12'h201);
|
200 |
|
|
assign wr_coun = WRITE & (ADDR[31:20] == 12'h205) & ADDR[2];
|
201 |
|
|
|
202 |
|
|
assign wr_leds = WRITE & (ADDR[31:20] == 12'h204);
|
203 |
|
|
|
204 |
|
|
always @(posedge BCLK) if (wr_leds && ADDR[2] && BE[1]) HEXM <= IO_DI[14:8];
|
205 |
|
|
always @(posedge BCLK) if (wr_leds && ADDR[2] && BE[0]) HEXL <= IO_DI[6:0];
|
206 |
|
|
always @(posedge BCLK) if (wr_leds && !ADDR[2] && BE[2]) LEDG <= IO_DI[23:16];
|
207 |
|
|
always @(posedge BCLK) if (wr_leds && !ADDR[2] && BE[1]) LEDR[9:8] <= IO_DI[9:8];
|
208 |
|
|
always @(posedge BCLK) if (wr_leds && !ADDR[2] && BE[0]) LEDR[7:0] <= IO_DI[7:0];
|
209 |
|
|
|
210 |
|
|
always @(posedge BCLK) ssw_reg <= SSW;
|
211 |
|
|
|
212 |
|
|
always @(posedge BCLK) rd_rdy <= READ & ((ADDR[31:20] == 12'h200) | (ADDR[31:29] == 3'd0)) & ~rd_rdy;
|
213 |
|
|
|
214 |
|
|
always @(access or ADDR or WRITE or rd_rdy or SRAM_RDY)
|
215 |
|
|
casex({access,ADDR[31:20]})
|
216 |
|
|
13'b1_000x_xxxx_xxxx : READY = rd_rdy; // if DRAM not activ
|
217 |
|
|
13'b1_0010_xxxx_0000 : READY = rd_rdy; // Boot-ROM
|
218 |
|
|
13'b1_0010_xxxx_0001 : READY = SRAM_RDY;
|
219 |
|
|
default : READY = access; // else only one clock !!!
|
220 |
|
|
endcase
|
221 |
|
|
|
222 |
|
|
always @(ADDR or BOOT_Q or SRAM_Q or UART_Q or ssw_reg or counter or nmie)
|
223 |
|
|
casex({ADDR[31:20]})
|
224 |
|
|
12'h201 : DRD = SRAM_Q;
|
225 |
|
|
12'h202 : DRD = UART_Q;
|
226 |
|
|
12'h203 : DRD = {22'd0,ssw_reg[9:0]};
|
227 |
|
|
12'h205 : DRD = {(ADDR[2] ? nmie : 1'd0),5'd0,counter};
|
228 |
|
|
default : DRD = BOOT_Q; // Boot-ROM
|
229 |
|
|
endcase
|
230 |
|
|
|
231 |
|
|
// Program access in higher ROM area switches DRAM on
|
232 |
|
|
always @(posedge BCLK) ENDRAM <= (((ADDR[31:28] == 4'h2) & (STATUS == 4'h8) & READ) | ENDRAM) & BRESET;
|
233 |
|
|
|
234 |
|
|
// ++++++++++++++++++++++++++ NMI Counter ++++++++++++++++++++++++++
|
235 |
|
|
|
236 |
|
|
always @(posedge BCLK)
|
237 |
|
|
if (!BRESET) counter <= 26'd0;
|
238 |
|
|
else counter <= (counter == 26'h2FA_F07F) ? 26'd0 : counter + 26'd1; // 50.000.000 = 2FA_F080
|
239 |
|
|
|
240 |
|
|
always @(posedge BCLK) NMI_N <= ~((counter[25:4] == 22'h2FA_F07) & nmie); // once per second
|
241 |
|
|
|
242 |
|
|
always @(posedge BCLK or negedge BRESET) // NMI Enable
|
243 |
|
|
if (!BRESET) nmie <= 1'b0;
|
244 |
|
|
else if (wr_coun) nmie <= IO_DI[31]; // is SET able
|
245 |
|
|
|
246 |
|
|
// ++++++++++++++++++++++++++ RESET Signal ++++++++++++++++++++++++++
|
247 |
|
|
|
248 |
|
|
always @(posedge BCLK or negedge RST_N)
|
249 |
|
|
if (!RST_N) init_cou <= 4'h0;
|
250 |
|
|
else init_cou <= init_cou + 4'h1;
|
251 |
|
|
|
252 |
|
|
always @(posedge BCLK or negedge RST_N)
|
253 |
|
|
if (!RST_N) BRESET <= 1'b0;
|
254 |
|
|
else
|
255 |
|
|
if (init_cou == 4'hF) BRESET <= 1'b1;
|
256 |
|
|
|
257 |
|
|
endmodule
|
258 |
|
|
|
259 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
260 |
|
|
//
|
261 |
|
|
// 3. UART Universal Asynchronous Receiver & Transmitter
|
262 |
|
|
//
|
263 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
264 |
|
|
module UART(BCLK, BRESET, UART_RD, UART_WR, DIN, UA_RX, UA_TX, UART_Q, UA_INT);
|
265 |
|
|
|
266 |
|
|
input BCLK;
|
267 |
|
|
input BRESET;
|
268 |
|
|
input UART_RD;
|
269 |
|
|
input [1:0] UART_WR;
|
270 |
|
|
input [15:0] DIN;
|
271 |
|
|
|
272 |
|
|
output UA_TX;
|
273 |
|
|
input UA_RX;
|
274 |
|
|
|
275 |
|
|
output [31:0] UART_Q;
|
276 |
|
|
output UA_INT;
|
277 |
|
|
|
278 |
|
|
reg [1:0] iena; // Interrupt enable
|
279 |
|
|
|
280 |
|
|
parameter baudrate = 10'd867; // 57600 Baud : 868 clocks of 20ns
|
281 |
|
|
|
282 |
|
|
// +++++++++++++++++++++++++++++++ Transmitter +++++++++++++++++++++++++++++++++
|
283 |
|
|
|
284 |
|
|
reg [8:0] shifter_tx;
|
285 |
|
|
reg [3:0] txbits;
|
286 |
|
|
reg [9:0] txtimer;
|
287 |
|
|
reg tx_int;
|
288 |
|
|
reg trold;
|
289 |
|
|
|
290 |
|
|
wire tx_load,tx_run,tx_shift;
|
291 |
|
|
|
292 |
|
|
assign tx_load = UART_WR[0] & ~tx_run; // no Write during transmisson
|
293 |
|
|
|
294 |
|
|
always @(posedge BCLK or negedge BRESET)
|
295 |
|
|
if (!BRESET) shifter_tx <= 9'h1FF;
|
296 |
|
|
else
|
297 |
|
|
if (tx_load) shifter_tx <= {DIN[7:0],1'b0};
|
298 |
|
|
else
|
299 |
|
|
if (tx_shift) shifter_tx <= {1'b1,shifter_tx[8:1]}; // LSB first to send
|
300 |
|
|
|
301 |
|
|
assign UA_TX = shifter_tx[0];
|
302 |
|
|
|
303 |
|
|
// ---1__2_one_3_two_4_three_5_four_6_five_7_six_8_seven_9_eight_10---11
|
304 |
|
|
always @(posedge BCLK or negedge BRESET)
|
305 |
|
|
if (!BRESET) txbits <= 4'd0;
|
306 |
|
|
else
|
307 |
|
|
if (tx_load) txbits <= 4'd1;
|
308 |
|
|
else
|
309 |
|
|
if (tx_shift) txbits <= (txbits == 4'd10) ? 4'd0 : txbits + 4'd1;
|
310 |
|
|
|
311 |
|
|
assign tx_run = |txbits;
|
312 |
|
|
always @(posedge BCLK) trold <= tx_run;
|
313 |
|
|
|
314 |
|
|
always @(posedge BCLK) txtimer <= (~tx_run | tx_shift) ? 10'd0 : txtimer + 10'd1;
|
315 |
|
|
|
316 |
|
|
assign tx_shift = (txtimer == baudrate);
|
317 |
|
|
|
318 |
|
|
always @(posedge BCLK or negedge BRESET)
|
319 |
|
|
if (!BRESET) tx_int <= 1'b0;
|
320 |
|
|
else
|
321 |
|
|
if (tx_load) tx_int <= 1'b0;
|
322 |
|
|
else
|
323 |
|
|
if (UART_WR[1]) tx_int <= DIN[13];
|
324 |
|
|
else
|
325 |
|
|
if (!tx_run && trold) tx_int <= 1'b1;
|
326 |
|
|
|
327 |
|
|
// +++++++++++++++++++++++++++++++ Receiver +++++++++++++++++++++++++++++++++
|
328 |
|
|
|
329 |
|
|
reg [2:0] inshift;
|
330 |
|
|
reg [3:0] rxbits;
|
331 |
|
|
reg [8:0] shifter_rx;
|
332 |
|
|
reg [9:0] rxtimer;
|
333 |
|
|
reg [7:0] rxhold;
|
334 |
|
|
reg inbit,oldin;
|
335 |
|
|
reg rx_int;
|
336 |
|
|
reg rx_end;
|
337 |
|
|
|
338 |
|
|
wire rx_go,rx_shift,rx_run;
|
339 |
|
|
|
340 |
|
|
always @(posedge BCLK) inshift <= {inshift[1:0],UA_RX};
|
341 |
|
|
|
342 |
|
|
always @(posedge BCLK) inbit <= (inshift == 3'b111) ? 1'b1 : (inshift == 3'd0) ? 1'b0 : inbit;
|
343 |
|
|
|
344 |
|
|
always @(posedge BCLK) oldin <= inbit;
|
345 |
|
|
|
346 |
|
|
assign rx_go = ~inbit & oldin & (rxbits == 4'd0);
|
347 |
|
|
|
348 |
|
|
// --1_2__3one_4two_5three_6four_7five_8six_9seven_10eight_-11--
|
349 |
|
|
always @(posedge BCLK or negedge BRESET)
|
350 |
|
|
if (!BRESET) rxbits <= 4'd0;
|
351 |
|
|
else
|
352 |
|
|
if (rx_go) rxbits <= 4'd1;
|
353 |
|
|
else
|
354 |
|
|
if (rx_shift) rxbits <= (((rxbits == 4'd1) & inbit) | (rxbits == 4'd10)) ? 4'd0 : rxbits + 4'd1;
|
355 |
|
|
|
356 |
|
|
always @(posedge BCLK) if (rx_shift) shifter_rx <= {inbit,shifter_rx[8:1]};
|
357 |
|
|
|
358 |
|
|
always @(posedge BCLK) rxtimer <= (~rx_run | rx_shift) ? 10'd0 : rxtimer + 10'd1;
|
359 |
|
|
|
360 |
|
|
assign rx_shift = (rxtimer == ((rxbits == 4'd1) ? {1'b0,baudrate[9:1]} : baudrate));
|
361 |
|
|
assign rx_run = |rxbits;
|
362 |
|
|
|
363 |
|
|
always @(posedge BCLK) rx_end <= rx_shift & (rxbits == 4'd10) & inbit; // Stopbit must be "1"
|
364 |
|
|
|
365 |
|
|
always @(posedge BCLK or negedge BRESET)
|
366 |
|
|
if (!BRESET) rx_int <= 1'b0;
|
367 |
|
|
else
|
368 |
|
|
if (UART_RD) rx_int <= 1'b0;
|
369 |
|
|
else
|
370 |
|
|
if (UART_WR[1]) rx_int <= DIN[10];
|
371 |
|
|
else
|
372 |
|
|
if (rx_end) rx_int <= 1'b1;
|
373 |
|
|
|
374 |
|
|
always @(posedge BCLK) if (rx_end) rxhold <= shifter_rx[7:0]; // hold received data
|
375 |
|
|
|
376 |
|
|
assign UART_Q = {18'd0,tx_int,iena[1],tx_run,rx_int,iena[0],rx_run,rxhold};
|
377 |
|
|
|
378 |
|
|
// +++++++++++++++++++++++++++++++ Interrupt +++++++++++++++++++++++++++++++++
|
379 |
|
|
|
380 |
|
|
always @(posedge BCLK or negedge BRESET)
|
381 |
|
|
if (!BRESET) iena <= 2'd0;
|
382 |
|
|
else
|
383 |
|
|
if (UART_WR[1]) iena <= {DIN[12],DIN[9]};
|
384 |
|
|
|
385 |
|
|
assign UA_INT = (tx_int & iena[1]) | (rx_int & iena[0]);
|
386 |
|
|
|
387 |
|
|
endmodule
|
388 |
|
|
|
389 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
390 |
|
|
//
|
391 |
|
|
// 4. SRAM External SRAM Interface
|
392 |
|
|
//
|
393 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
394 |
|
|
module SRAM (BCLK, BRESET, CESRAM, WRITE, AA, BE, DIN, READY, SRAM_Q, SRCO, SRAA, SRDB);
|
395 |
|
|
|
396 |
|
|
input BCLK;
|
397 |
|
|
input BRESET;
|
398 |
|
|
input CESRAM;
|
399 |
|
|
input WRITE;
|
400 |
|
|
input [18:1] AA;
|
401 |
|
|
input [3:0] BE;
|
402 |
|
|
input [31:0] DIN;
|
403 |
|
|
|
404 |
|
|
output READY;
|
405 |
|
|
output [31:0] SRAM_Q;
|
406 |
|
|
|
407 |
|
|
output reg [4:0] SRCO;
|
408 |
|
|
output reg [17:0] SRAA; // Word Address
|
409 |
|
|
inout [15:0] SRDB;
|
410 |
|
|
|
411 |
|
|
reg [15:0] do_reg;
|
412 |
|
|
reg [2:0] state;
|
413 |
|
|
reg [17:0] save_aa;
|
414 |
|
|
reg [1:0] top_be,save_be,muxbe;
|
415 |
|
|
reg [15:0] top_do,save_do,muxdo;
|
416 |
|
|
reg [15:0] di_reg,pipe_reg;
|
417 |
|
|
reg [15:0] oe_reg;
|
418 |
|
|
|
419 |
|
|
wire twoa;
|
420 |
|
|
wire [17:0] muxadr;
|
421 |
|
|
|
422 |
|
|
genvar i;
|
423 |
|
|
|
424 |
|
|
assign twoa = (BE[3] | BE[2]) & (BE[1] | BE[0]); // two Accesses
|
425 |
|
|
|
426 |
|
|
always @(posedge BCLK or negedge BRESET)
|
427 |
|
|
if (!BRESET) state <= 3'd0;
|
428 |
|
|
else
|
429 |
|
|
casex ({CESRAM,WRITE,twoa,state})
|
430 |
|
|
6'b0x_x_000 : state <= 3'b000; // nothing to do
|
431 |
|
|
6'b10_1_000 : state <= 3'b001;
|
432 |
|
|
6'b10_0_000 : state <= 3'b010;
|
433 |
|
|
6'b11_1_000 : state <= 3'b100;
|
434 |
|
|
6'b11_0_000 : state <= 3'b110;
|
435 |
|
|
// Read
|
436 |
|
|
6'bxx_x_001 : state <= 3'b010;
|
437 |
|
|
6'bxx_x_010 : state <= 3'b011;
|
438 |
|
|
6'bxx_x_011 : state <= 3'b000; // Send READY
|
439 |
|
|
// Write
|
440 |
|
|
6'bxx_x_100 : state <= 3'b101;
|
441 |
|
|
6'bxx_x_101 : state <= 3'b110;
|
442 |
|
|
6'bxx_x_110 : state <= 3'b000; // State 7 at WRITE overlaps with State 0
|
443 |
|
|
default : state <= 3'b000;
|
444 |
|
|
endcase
|
445 |
|
|
|
446 |
|
|
always @(posedge BCLK) save_aa <= muxadr;
|
447 |
|
|
|
448 |
|
|
assign muxadr[17:1] = (CESRAM & (state == 3'd0)) ? AA[18:2] : save_aa[17:1];
|
449 |
|
|
assign muxadr[0] = (CESRAM & (state == 3'd0)) ? AA[1] : ( ((state == 3'd1) | (state == 3'd5)) ? 1'b1 : save_aa[0] );
|
450 |
|
|
|
451 |
|
|
always @(posedge BCLK) SRAA <= muxadr;
|
452 |
|
|
|
453 |
|
|
always @(posedge BCLK) if (!state[2]) top_be = ~BE[3:2];
|
454 |
|
|
always @(posedge BCLK) save_be <= muxbe;
|
455 |
|
|
|
456 |
|
|
always @(*)
|
457 |
|
|
casex ({CESRAM,state})
|
458 |
|
|
4'b0_000 : muxbe = 2'b11;
|
459 |
|
|
4'b1_000 : muxbe = AA[1] ? ~BE[3:2] : ~BE[1:0]; // READ has valid BE's
|
460 |
|
|
4'bx_001 : muxbe = ~BE[3:2]; // READ is still active
|
461 |
|
|
4'bx_101 : muxbe = top_be;
|
462 |
|
|
4'bx_010 : muxbe = 2'b11; // State = 2 is End for READ !
|
463 |
|
|
default : muxbe = save_be;
|
464 |
|
|
endcase
|
465 |
|
|
|
466 |
|
|
always @(posedge BCLK) SRCO[1:0] <= muxbe;
|
467 |
|
|
|
468 |
|
|
always @(posedge BCLK) if (!state[2]) top_do <= DIN[31:16];
|
469 |
|
|
always @(posedge BCLK) save_do <= muxdo;
|
470 |
|
|
|
471 |
|
|
always @(*)
|
472 |
|
|
casex ({CESRAM,state})
|
473 |
|
|
4'b1_000 : muxdo = AA[1] ? DIN[31:16] : DIN[15:0]; // READ has valid BE's
|
474 |
|
|
4'bx_101 : muxdo = top_do;
|
475 |
|
|
default : muxdo = save_do;
|
476 |
|
|
endcase
|
477 |
|
|
|
478 |
|
|
always @(posedge BCLK) do_reg <= muxdo;
|
479 |
|
|
|
480 |
|
|
// Control Signals
|
481 |
|
|
always @(posedge BCLK) SRCO[4] <= ~((CESRAM & (state == 3'd0)) | (state == 3'd1) | (state == 3'd4) | (state == 3'd5) | (state == 3'd6)); // CE
|
482 |
|
|
always @(posedge BCLK) SRCO[3] <= ~((CESRAM & ~WRITE & (state == 3'd0)) | (state == 3'd1)); // OE
|
483 |
|
|
always @(negedge BCLK) SRCO[2] <= ~((state == 3'd4) | (state == 3'd6)); // WE
|
484 |
|
|
|
485 |
|
|
always @(posedge BCLK) oe_reg <= {16{(CESRAM & WRITE & (state == 3'd0)) | (state == 3'd4) | (state == 3'd5) | (state == 3'd6)}};
|
486 |
|
|
|
487 |
|
|
generate
|
488 |
|
|
for (i=0;i<=15;i=i+1)
|
489 |
|
|
begin: oectrl
|
490 |
|
|
assign SRDB[i] = oe_reg[i] ? do_reg[i] : 1'bz;
|
491 |
|
|
end
|
492 |
|
|
endgenerate
|
493 |
|
|
|
494 |
|
|
always @(posedge BCLK) di_reg <= SRDB; // Fast Input Register
|
495 |
|
|
always @(posedge BCLK) pipe_reg <= di_reg;
|
496 |
|
|
|
497 |
|
|
assign SRAM_Q = {di_reg,(twoa ? pipe_reg : di_reg)};
|
498 |
|
|
assign READY = CESRAM & (WRITE ? (state == 3'd0) : (state == 3'd3));
|
499 |
|
|
|
500 |
|
|
endmodule
|
501 |
|
|
|
502 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
503 |
|
|
//
|
504 |
|
|
// 5. TRIPUTER Top level of FPGA
|
505 |
|
|
//
|
506 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
507 |
|
|
module TRIPUTER( RCLK, RST_N, SSW, UA_TX, UA_RX, SRCO, SRAA, SRDB, HEXM, HEXL, LEDR, LEDG, AUD_XCK, HDMI_CLK );
|
508 |
|
|
|
509 |
|
|
input RCLK;
|
510 |
|
|
input RST_N;
|
511 |
|
|
|
512 |
|
|
input [9:0] SSW;
|
513 |
|
|
|
514 |
|
|
input UA_RX;
|
515 |
|
|
output UA_TX;
|
516 |
|
|
|
517 |
|
|
output [4:0] SRCO;
|
518 |
|
|
output [17:0] SRAA;
|
519 |
|
|
inout [15:0] SRDB;
|
520 |
|
|
|
521 |
|
|
output [6:0] HEXM,HEXL;
|
522 |
|
|
output [9:0] LEDR;
|
523 |
|
|
output [7:0] LEDG;
|
524 |
|
|
|
525 |
|
|
output AUD_XCK,HDMI_CLK; // only driving 0
|
526 |
|
|
|
527 |
|
|
reg [31:0] BOOT_ROM [0:511]; // 2 kByte
|
528 |
|
|
reg [31:0] BOOT_Q;
|
529 |
|
|
|
530 |
|
|
wire [31:0] AA;
|
531 |
|
|
wire NMI_N;
|
532 |
|
|
wire BCLK;
|
533 |
|
|
wire DC_ACC;
|
534 |
|
|
wire DC_WR;
|
535 |
|
|
wire DC_MDONE;
|
536 |
|
|
wire [31:0] DIN;
|
537 |
|
|
wire [28:0] DRAM_ADR;
|
538 |
|
|
wire [35:0] DRAM_DI;
|
539 |
|
|
wire [127:0] DRAM_Q;
|
540 |
|
|
wire [31:0] DRD;
|
541 |
|
|
wire DC_INHIBIT;
|
542 |
|
|
wire IC_ACC;
|
543 |
|
|
wire IC_MDONE;
|
544 |
|
|
wire [28:0] IDRAM_ADR;
|
545 |
|
|
wire IC_INHIBIT;
|
546 |
|
|
wire READ;
|
547 |
|
|
wire READY;
|
548 |
|
|
wire [3:0] STATUS;
|
549 |
|
|
wire ENDRAM;
|
550 |
|
|
wire ENWR;
|
551 |
|
|
wire WRITE;
|
552 |
|
|
wire [3:0] BE;
|
553 |
|
|
wire CESRAM;
|
554 |
|
|
wire [31:0] SRAM_Q;
|
555 |
|
|
wire SRAM_RDY;
|
556 |
|
|
wire BRESET;
|
557 |
|
|
wire INT_N;
|
558 |
|
|
wire UART_RD;
|
559 |
|
|
wire [1:0] UART_WR;
|
560 |
|
|
wire [31:0] UART_Q;
|
561 |
|
|
|
562 |
|
|
assign BCLK = RCLK;
|
563 |
|
|
assign AUD_XCK = 1'b0;
|
564 |
|
|
assign HDMI_CLK = 1'b0;
|
565 |
|
|
|
566 |
|
|
M32632 CPU(
|
567 |
|
|
.BCLK(BCLK),
|
568 |
|
|
.BRESET(BRESET),
|
569 |
|
|
.DRAMSZ(3'b010),
|
570 |
|
|
.NMI_N(NMI_N),
|
571 |
|
|
.INT_N(~INT_N),
|
572 |
|
|
.IC_MDONE(IC_MDONE),
|
573 |
|
|
.IC_INHIBIT(IC_INHIBIT),
|
574 |
|
|
.DRAM_Q(DRAM_Q),
|
575 |
|
|
.ENWR(ENWR),
|
576 |
|
|
.DC_MDONE(DC_MDONE),
|
577 |
|
|
.DC_INHIBIT(DC_INHIBIT),
|
578 |
|
|
.ENDRAM(ENDRAM),
|
579 |
|
|
.COP_DONE(1'b0),
|
580 |
|
|
.COP_IN(64'd0),
|
581 |
|
|
.HOLD(1'b1),
|
582 |
|
|
.DMA_CHK(1'b0),
|
583 |
|
|
.DMA_AA(25'd0),
|
584 |
|
|
.IO_READY(READY),
|
585 |
|
|
.IO_Q(DRD),
|
586 |
|
|
// Outputs:
|
587 |
|
|
.STATUS(STATUS),
|
588 |
|
|
.ILO(),
|
589 |
|
|
.STATSIGS(),
|
590 |
|
|
.IC_ACC(IC_ACC),
|
591 |
|
|
.IDRAM_ADR(IDRAM_ADR),
|
592 |
|
|
.DC_WR(DC_WR),
|
593 |
|
|
.DC_ACC(DC_ACC),
|
594 |
|
|
.DRAM_ADR(DRAM_ADR),
|
595 |
|
|
.DRAM_DI(DRAM_DI),
|
596 |
|
|
.COP_GO(),
|
597 |
|
|
.COP_OP(),
|
598 |
|
|
.COP_OUT(),
|
599 |
|
|
.HLDA(),
|
600 |
|
|
.IO_RD(READ),
|
601 |
|
|
.IO_WR(WRITE),
|
602 |
|
|
.IO_A(AA),
|
603 |
|
|
.IO_BE(BE),
|
604 |
|
|
.IO_DI(DIN) );
|
605 |
|
|
|
606 |
|
|
DRAM_MOD DRAM(
|
607 |
|
|
.MCLK(BCLK),
|
608 |
|
|
.RST_N(BRESET),
|
609 |
|
|
.IC_ACC(IC_ACC),
|
610 |
|
|
.IDRAM_ADR(IDRAM_ADR),
|
611 |
|
|
.DC_WR(DC_WR),
|
612 |
|
|
.DC_ACC(DC_ACC),
|
613 |
|
|
.DRAM_ADR(DRAM_ADR),
|
614 |
|
|
.DRAM_DI(DRAM_DI),
|
615 |
|
|
.IC_MDONE(IC_MDONE),
|
616 |
|
|
.IC_INHIBIT(IC_INHIBIT),
|
617 |
|
|
.MEM_Q(DRAM_Q),
|
618 |
|
|
.ENWR(ENWR),
|
619 |
|
|
.DC_MDONE(DC_MDONE),
|
620 |
|
|
.DC_INHIBIT(DC_INHIBIT) );
|
621 |
|
|
|
622 |
|
|
|
623 |
|
|
MAINDEC MDEC(
|
624 |
|
|
.BCLK(BCLK),
|
625 |
|
|
.WRITE(WRITE),
|
626 |
|
|
.READ(READ),
|
627 |
|
|
.ADDR(AA[31:2]),
|
628 |
|
|
.STATUS(STATUS),
|
629 |
|
|
.IO_DI(DIN),
|
630 |
|
|
.SRAM_RDY(SRAM_RDY),
|
631 |
|
|
.SRAM_Q(SRAM_Q),
|
632 |
|
|
.BOOT_Q(BOOT_Q),
|
633 |
|
|
.UART_Q(UART_Q),
|
634 |
|
|
.BE(BE),
|
635 |
|
|
.RST_N(RST_N),
|
636 |
|
|
.SSW(SSW),
|
637 |
|
|
.READY(READY),
|
638 |
|
|
.DRD(DRD),
|
639 |
|
|
.ENDRAM(ENDRAM),
|
640 |
|
|
.BRESET(BRESET),
|
641 |
|
|
.LEDR(LEDR),
|
642 |
|
|
.LEDG(LEDG),
|
643 |
|
|
.HEXM(HEXM),
|
644 |
|
|
.HEXL(HEXL),
|
645 |
|
|
.NMI_N(NMI_N),
|
646 |
|
|
.UART_RD(UART_RD),
|
647 |
|
|
.UART_WR(UART_WR),
|
648 |
|
|
.CESRAM(CESRAM) );
|
649 |
|
|
|
650 |
|
|
UART SERIF(
|
651 |
|
|
.BCLK(BCLK),
|
652 |
|
|
.BRESET(BRESET),
|
653 |
|
|
.UART_RD(UART_RD),
|
654 |
|
|
.UART_WR(UART_WR),
|
655 |
|
|
.DIN(DIN[15:0]),
|
656 |
|
|
.UART_Q(UART_Q),
|
657 |
|
|
.UA_INT(INT_N),
|
658 |
|
|
.UA_RX(UA_RX),
|
659 |
|
|
.UA_TX(UA_TX) );
|
660 |
|
|
|
661 |
|
|
SRAM SRAMIF(
|
662 |
|
|
.BCLK(BCLK),
|
663 |
|
|
.BRESET(BRESET),
|
664 |
|
|
.CESRAM(CESRAM),
|
665 |
|
|
.WRITE(WRITE),
|
666 |
|
|
.AA(AA[18:1]),
|
667 |
|
|
.DIN(DIN),
|
668 |
|
|
.BE(BE),
|
669 |
|
|
.SRAM_Q(SRAM_Q),
|
670 |
|
|
.READY(SRAM_RDY),
|
671 |
|
|
.SRCO(SRCO),
|
672 |
|
|
.SRAA(SRAA),
|
673 |
|
|
.SRDB(SRDB) );
|
674 |
|
|
|
675 |
|
|
initial
|
676 |
|
|
begin
|
677 |
|
|
$readmemh("boot_rom.txt", BOOT_ROM);
|
678 |
|
|
end
|
679 |
|
|
|
680 |
|
|
always @(posedge BCLK) BOOT_Q <= BOOT_ROM[AA[10:2]];
|
681 |
|
|
|
682 |
|
|
endmodule
|