Wishbone接口Altera JTAG UART

  某些时候,我们在使用Altera FPGA的时候,尤其是涉及SoC系统的时候,通常需要一个串口与PC交互。使用Altera的USB-Blaster免去了外接一个串口。我们可以使用下面所述的IP核通过USB-Blaster将PC的字符传入FPGA或者从FPGA将字符数据发送至PC。

 1 alt_jtag_atlantic jtag_uart_alt_jtag_atlantic
 2 (
 3     .clk (clk),
 4     .r_dat (r_dat),
 5     .r_ena (r_ena),
 6     .r_val (r_val),
 7     .rst_n (rst_n),
 8     .t_dat (t_dat),
 9     .t_dav (t_dav),
10     .t_ena (t_ena),
11     .t_pause (t_pause)
12      );
13     
14     defparam jtag_uart_alt_jtag_atlantic.INSTANCE_ID = 0,
15          jtag_uart_alt_jtag_atlantic.LOG2_RXFIFO_DEPTH = 6,
16          jtag_uart_alt_jtag_atlantic.LOG2_TXFIFO_DEPTH = 6,
17          jtag_uart_alt_jtag_atlantic.SLD_AUTO_INSTANCE_INDEX = "YES";

  下面贴出一个Wishbone接口的JTAG UART的代码描述:

  1 // synthesis translate_off
  2 `timescale 1ns / 1ps
  3 // synthesis translate_on
  4 
  5 module wb_jtag_uart (
  6     input           clk_i,
  7     input            rst_i,
  8 
  9     input            wb_stb_i,
 10     input            wb_cyc_i,
 11     output          wb_ack_o,
 12     input            wb_adr_i,
 13     input            wb_we_i,
 14     input   [31:0]     wb_dat_i,
 15     output  [31:0]    wb_dat_o,
 16     output            wb_irq_o
 17 );
 18 
 19 /* synthesis ALTERA_ATTRIBUTE = "SUPPRESS_DA_RULE_INTERNAL="R101,C106,D101,D103"" */
 20 
 21 reg              ac;
 22 wire             activity;
 23 wire             av_irq;
 24 wire    [ 31: 0] av_readdata;
 25 wire    [ 31: 0] av_writedata;
 26 reg              av_waitrequest;
 27 reg              fifo_AE;
 28 reg              fifo_AF;
 29 wire             fifo_EF;
 30 wire             fifo_FF;
 31 wire             fifo_clear;
 32 wire             fifo_rd;
 33 wire    [  7: 0] fifo_rdata;
 34 wire    [  7: 0] fifo_wdata;
 35 reg              fifo_wr;
 36 reg              ien_AE;
 37 reg              ien_AF;
 38 wire             ipen_AE;
 39 wire             ipen_AF;
 40 reg              pause_irq;
 41 wire    [  7: 0] r_dat;
 42 wire             r_ena;
 43 reg              r_val;
 44 wire             rd_wfifo;
 45 reg              read_0;
 46 wire             rfifo_full;
 47 wire    [  5: 0] rfifo_used;
 48 reg              rvalid;
 49 reg              sim_r_ena;
 50 reg              sim_t_dat;
 51 reg              sim_t_ena;
 52 reg              sim_t_pause;
 53 wire    [  7: 0] t_dat;
 54 reg              t_dav;
 55 wire             t_ena;
 56 wire             t_pause;
 57 wire             wfifo_empty;
 58 wire    [  5: 0] wfifo_used;
 59 reg              woverflow;
 60 wire             wr_rfifo;
 61 wire             clk;
 62 wire             rst_n;
 63 wire             av_read_n;
 64 wire             av_write_n;
 65 wire             av_address;
 66 wire             av_chipselect;
 67 
 68 assign    clk = clk_i;
 69 assign     rst_n = ~rst_i;
 70 assign    av_address =  wb_adr_i;
 71 assign    wb_dat_o = av_readdata;
 72 assign    av_writedata = wb_dat_i;
 73 assign    wb_irq_o = av_irq;
 74 assign    wb_ack_o = ~av_waitrequest;
 75 assign    av_read_n = ~(wb_cyc_i & wb_stb_i & (~wb_we_i));
 76 assign    av_write_n = ~(wb_cyc_i & wb_stb_i & wb_we_i);
 77 assign    av_chipselect = wb_cyc_i & wb_stb_i;
 78 
 79 //avalon_jtag_slave, which is an e_avalon_slave
 80 assign rd_wfifo = r_ena & ~wfifo_empty;
 81 assign wr_rfifo = t_ena & ~rfifo_full;
 82 assign fifo_clear = ~rst_n;
 83 wb_jtag_uart_scfifo_w jtag_uart_scfifo_w
 84 (
 85   .clk         (clk),
 86   .fifo_FF     (fifo_FF),
 87   .fifo_clear  (fifo_clear),
 88   .fifo_wdata  (fifo_wdata),
 89   .fifo_wr     (fifo_wr),
 90   .r_dat       (r_dat),
 91   .rd_wfifo    (rd_wfifo),
 92   .wfifo_empty (wfifo_empty),
 93   .wfifo_used  (wfifo_used)
 94 );
 95 
 96 wb_jtag_uart_scfifo_r jtag_uart_scfifo_r
 97 (
 98   .clk        (clk),
 99   .fifo_EF    (fifo_EF),
100   .fifo_clear (fifo_clear),
101   .fifo_rd    (fifo_rd),
102   .fifo_rdata (fifo_rdata),
103   .rfifo_full (rfifo_full),
104   .rfifo_used (rfifo_used),
105   .rst_n      (rst_n),
106   .t_dat      (t_dat),
107   .wr_rfifo   (wr_rfifo)
108 );
109 
110 assign ipen_AE = ien_AE & fifo_AE;
111 assign ipen_AF = ien_AF & (pause_irq | fifo_AF);
112 assign av_irq = ipen_AE | ipen_AF;
113 assign activity = t_pause | t_ena;
114 always @(posedge clk or negedge rst_n)
115 begin
116   if (rst_n == 0)
117       pause_irq <= 1'b0;
118   else // only if fifo is not empty...
119   if (t_pause & ~fifo_EF)
120       pause_irq <= 1'b1;
121   else if (read_0)
122       pause_irq <= 1'b0;
123 end
124 
125 
126 always @(posedge clk or negedge rst_n)
127 begin
128   if (rst_n == 0)
129     begin
130       r_val <= 1'b0;
131       t_dav <= 1'b1;
132     end
133   else 
134     begin
135       r_val <= r_ena & ~wfifo_empty;
136       t_dav <= ~rfifo_full;
137     end
138 end
139 
140 
141 always @(posedge clk or negedge rst_n)
142 begin
143   if (rst_n == 0)
144     begin
145       fifo_AE <= 1'b0;
146       fifo_AF <= 1'b0;
147       fifo_wr <= 1'b0;
148       rvalid <= 1'b0;
149       read_0 <= 1'b0;
150       ien_AE <= 1'b0;
151       ien_AF <= 1'b0;
152       ac <= 1'b0;
153       woverflow <= 1'b0;
154       av_waitrequest <= 1'b1;
155     end
156   else 
157     begin
158       fifo_AE <= {fifo_FF,wfifo_used} <= 8;
159       fifo_AF <= (7'h40 - {rfifo_full,rfifo_used}) <= 8;
160       fifo_wr <= 1'b0;
161       read_0 <= 1'b0;
162       av_waitrequest <= ~(av_chipselect & (~av_write_n | ~av_read_n) & av_waitrequest);
163       if (activity)
164           ac <= 1'b1;
165       // write
166       if (av_chipselect & ~av_write_n & av_waitrequest)
167           // addr 1 is control; addr 0 is data
168           if (av_address)
169             begin
170               ien_AF <= av_writedata[0];
171               ien_AE <= av_writedata[1];
172               if (av_writedata[10] & ~activity)
173                   ac <= 1'b0;
174             end
175           else 
176             begin
177               fifo_wr <= ~fifo_FF;
178               woverflow <= fifo_FF;
179             end
180       // read
181       if (av_chipselect & ~av_read_n & av_waitrequest)
182         begin
183           // addr 1 is interrupt; addr 0 is data
184           if (~av_address)
185               rvalid <= ~fifo_EF;
186           read_0 <= ~av_address;
187         end
188     end
189 end
190 
191 
192 assign fifo_wdata = av_writedata[7 : 0];
193 assign fifo_rd = (av_chipselect & ~av_read_n & av_waitrequest & ~av_address) ? ~fifo_EF : 1'b0;
194 assign av_readdata = read_0 ? { {9{1'b0}},rfifo_full,rfifo_used,rvalid,woverflow,~fifo_FF,~fifo_EF,1'b0,ac,ipen_AE,ipen_AF,fifo_rdata } : { {9{1'b0}},(7'h40 - {fifo_FF,wfifo_used}),rvalid,woverflow,~fifo_FF,~fifo_EF,1'b0,ac,ipen_AE,ipen_AF,{6{1'b0}},ien_AE,ien_AF };
195 
196 //synthesis read_comments_as_HDL on
197 //  alt_jtag_atlantic jtag_uart_alt_jtag_atlantic
198 //    (
199 //      .clk (clk),
200 //      .r_dat (r_dat),
201 //      .r_ena (r_ena),
202 //      .r_val (r_val),
203 //      .rst_n (rst_n),
204 //      .t_dat (t_dat),
205 //      .t_dav (t_dav),
206 //      .t_ena (t_ena),
207 //      .t_pause (t_pause)
208 //    );
209 //
210 //  defparam jtag_uart_alt_jtag_atlantic.INSTANCE_ID = 0,
211 //           jtag_uart_alt_jtag_atlantic.LOG2_RXFIFO_DEPTH = 6,
212 //           jtag_uart_alt_jtag_atlantic.LOG2_TXFIFO_DEPTH = 6,
213 //           jtag_uart_alt_jtag_atlantic.SLD_AUTO_INSTANCE_INDEX = "YES";
214 //
215 //
216 //synthesis read_comments_as_HDL off
217 
218 endmodule
219 
220 module wb_jtag_uart_scfifo_w (
221                                      // inputs:
222                                       clk,
223                                       fifo_clear,
224                                       fifo_wdata,
225                                       fifo_wr,
226                                       rd_wfifo,
227 
228                                      // outputs:
229                                       fifo_FF,
230                                       r_dat,
231                                       wfifo_empty,
232                                       wfifo_used
233                                    );
234 
235 output           fifo_FF;
236 output  [  7: 0] r_dat;
237 output           wfifo_empty;
238 output  [  5: 0] wfifo_used;
239 input            clk;
240 input            fifo_clear;
241 input   [  7: 0] fifo_wdata;
242 input            fifo_wr;
243 input            rd_wfifo;
244 
245 wire             fifo_FF;
246 wire    [  7: 0] r_dat;
247 wire             wfifo_empty;
248 wire    [  5: 0] wfifo_used;
249 
250 //synthesis read_comments_as_HDL on
251 //  scfifo wfifo
252 //    (
253 //      .aclr (fifo_clear),
254 //      .clock (clk),
255 //      .data (fifo_wdata),
256 //      .empty (wfifo_empty),
257 //      .full (fifo_FF),
258 //      .q (r_dat),
259 //      .rdreq (rd_wfifo),
260 //      .usedw (wfifo_used),
261 //      .wrreq (fifo_wr)
262 //    );
263 //
264 //  defparam wfifo.lpm_hint = "RAM_BLOCK_TYPE=AUTO",
265 //           wfifo.lpm_numwords = 64,
266 //           wfifo.lpm_showahead = "OFF",
267 //           wfifo.lpm_type = "scfifo",
268 //           wfifo.lpm_width = 8,
269 //           wfifo.lpm_widthu = 6,
270 //           wfifo.overflow_checking = "OFF",
271 //           wfifo.underflow_checking = "OFF",
272 //           wfifo.use_eab = "ON";
273 //
274 //synthesis read_comments_as_HDL off
275 
276 endmodule
277 
278 module wb_jtag_uart_scfifo_r (
279                                      // inputs:
280                                       clk,
281                                       fifo_clear,
282                                       fifo_rd,
283                                       rst_n,
284                                       t_dat,
285                                       wr_rfifo,
286 
287                                      // outputs:
288                                       fifo_EF,
289                                       fifo_rdata,
290                                       rfifo_full,
291                                       rfifo_used
292                                    );
293 output           fifo_EF;
294 output  [  7: 0] fifo_rdata;
295 output           rfifo_full;
296 output  [  5: 0] rfifo_used;
297 input            clk;
298 input            fifo_clear;
299 input            fifo_rd;
300 input            rst_n;
301 input   [  7: 0] t_dat;
302 input            wr_rfifo;
303 
304 wire             fifo_EF;
305 wire    [  7: 0] fifo_rdata;
306 wire             rfifo_full;
307 wire    [  5: 0] rfifo_used;
308 
309 //synthesis read_comments_as_HDL on
310 //  scfifo rfifo
311 //    (
312 //      .aclr (fifo_clear),
313 //      .clock (clk),
314 //      .data (t_dat),
315 //      .empty (fifo_EF),
316 //      .full (rfifo_full),
317 //      .q (fifo_rdata),
318 //      .rdreq (fifo_rd),
319 //      .usedw (rfifo_used),
320 //      .wrreq (wr_rfifo)
321 //    );
322 //
323 //  defparam rfifo.lpm_hint = "RAM_BLOCK_TYPE=AUTO",
324 //           rfifo.lpm_numwords = 64,
325 //           rfifo.lpm_showahead = "OFF",
326 //           rfifo.lpm_type = "scfifo",
327 //           rfifo.lpm_width = 8,
328 //           rfifo.lpm_widthu = 6,
329 //           rfifo.overflow_checking = "OFF",
330 //           rfifo.underflow_checking = "OFF",
331 //           rfifo.use_eab = "ON";
332 //
333 //synthesis read_comments_as_HDL off
334 
335 endmodule

  关于这个IP核(alt_jtag_atlantic)的寄存器的说明,在Altera的文档中有所说明。其实非常简单,只有两个32位的寄存器。

原文地址:https://www.cnblogs.com/lyuyangly/p/5550911.html