| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- module multi_uart_ip #(parameter
- UART_GROUP = 2, // Number of UART groups
- UART_COUNT = 6, // Number of UART instances in each group
- UART_TOTAL = UART_GROUP * UART_COUNT
- ) (
- // input [UART_TOTAL-1:0] uart_rxd,
- // output [UART_TOTAL-1:0] uart_txd,
-
- output tri0 SIM_CLK,
- inout [11:0] SIM_IO,
- inout SIM_IO_12,
- inout SIM_IO_13,
- inout SIM_IO_14,
- inout SIM_IO_15,
- input uart14_rx,
- output tri0 uart14_tx,
- input uart15_rx,
- output tri0 uart15_tx,
- output tri0 [3:0] ext_int_in,
- output tri0 [5:0] gpio_int_g0_in,
- output tri0 [5:0] gpio_int_g1_in,
- output tri0 rxd_12_ip_in,
- output tri0 rxd_13_ip_in,
- output tri0 rxd_14_ip_in,
- output tri0 rxd_15_ip_in,
- input txd_12_ip_out_data,
- input txd_12_ip_out_en,
- input txd_13_ip_out_data,
- input txd_13_ip_out_en,
- input txd_14_ip_out_data,
- input txd_14_ip_out_en,
- input txd_15_ip_out_data,
- input txd_15_ip_out_en,
- input txen_12_ip_out_data,
- input txen_12_ip_out_en,
- input txen_13_ip_out_data,
- input txen_13_ip_out_en,
- input txen_14_ip_out_data,
- input txen_14_ip_out_en,
- input txen_15_ip_out_data,
- input txen_15_ip_out_en,
- input sys_clock,
- input bus_clock,
- input resetn,
- input stop,
- input [1:0] mem_ahb_htrans,
- input mem_ahb_hready,
- input mem_ahb_hwrite,
- input [31:0] mem_ahb_haddr,
- input [2:0] mem_ahb_hsize,
- input [2:0] mem_ahb_hburst,
- input [31:0] mem_ahb_hwdata,
- output tri1 mem_ahb_hreadyout,
- output tri0 mem_ahb_hresp,
- output tri0 [31:0] mem_ahb_hrdata,
- output tri0 slave_ahb_hsel,
- output tri1 slave_ahb_hready,
- input slave_ahb_hreadyout,
- output tri0 [1:0] slave_ahb_htrans,
- output tri0 [2:0] slave_ahb_hsize,
- output tri0 [2:0] slave_ahb_hburst,
- output tri0 slave_ahb_hwrite,
- output tri0 [31:0] slave_ahb_haddr,
- output tri0 [31:0] slave_ahb_hwdata,
- input slave_ahb_hresp,
- input [31:0] slave_ahb_hrdata,
- output tri0 [3:0] ext_dma_DMACBREQ,
- output tri0 [3:0] ext_dma_DMACLBREQ,
- output tri0 [3:0] ext_dma_DMACSREQ,
- output tri0 [3:0] ext_dma_DMACLSREQ,
- input [3:0] ext_dma_DMACCLR,
- input [3:0] ext_dma_DMACTC,
- output tri0 [3:0] local_int
- );
- reg [UART_TOTAL-1:0] uart_tx_busy;
- wire [UART_TOTAL-1:0] uart_rxd;
- reg [UART_TOTAL-1:0] uart_txd;
- assign uart_rxd = uart_tx_busy | SIM_IO; // 接收
- genvar i;
- generate
- for (i = 0; i < UART_TOTAL; i = i + 1) begin : gen_sim_io
- assign SIM_IO[i] = uart_tx_busy[i] ? uart_txd[i] : 1'bz; // 发送
- end
- endgenerate
- assign SIM_IO_12 = (txen_12_ip_out_en && txen_12_ip_out_data) ? (txd_12_ip_out_en ? txd_12_ip_out_data : 1'bz) : 1'bz;
- assign rxd_12_ip_in = (txen_12_ip_out_en && txen_12_ip_out_data) ? 1'bz : SIM_IO_12;
- assign SIM_IO_13 = (txen_13_ip_out_en && txen_13_ip_out_data) ? (txd_13_ip_out_en ? txd_13_ip_out_data : 1'bz) : 1'bz;
- assign rxd_13_ip_in = (txen_13_ip_out_en && txen_13_ip_out_data) ? 1'bz : SIM_IO_13;
- // assign SIM_IO_14 = (txen_14_ip_out_en && txen_14_ip_out_data) ? (txd_14_ip_out_en ? txd_14_ip_out_data : 1'bz) : 1'bz;
- // assign rxd_14_ip_in = (txen_14_ip_out_en && txen_14_ip_out_data) ? 1'bz : SIM_IO_14;
- assign SIM_IO_14 = (txen_14_ip_out_en && txen_14_ip_out_data) ? (txd_14_ip_out_en ? txd_14_ip_out_data : 1'bz) : 1'bz;
- assign rxd_14_ip_in = txen_14_ip_out_en ? ((txen_14_ip_out_data) ? 1'bz : SIM_IO_14) : uart14_rx;
- assign uart14_tx = (!txen_14_ip_out_en) ? txd_14_ip_out_data : 1'bz;
- assign SIM_IO_15 = (txen_15_ip_out_en && txen_15_ip_out_data) ? (txd_15_ip_out_en ? txd_15_ip_out_data : 1'bz) : 1'bz;
- assign rxd_15_ip_in = txen_15_ip_out_en ? ((txen_15_ip_out_data) ? 1'bz : SIM_IO_15) : uart15_rx;
- // assign uart15_tx = (!txen_15_ip_out_en) ? (txd_15_ip_out_en ? txd_15_ip_out_data : 1'bz) : 1'bz;
- assign uart15_tx = (!txen_15_ip_out_en) ? txd_15_ip_out_data : 1'bz;
-
- parameter DATA_WIDTH = 8;
- parameter FIFO_DEPTH = 1;
- wire [UART_TOTAL-1:0] tx_dma_clr;
- wire [UART_TOTAL-1:0] tx_dma_req;
- wire [UART_TOTAL-1:0] rx_dma_clr;
- wire [UART_TOTAL-1:0] rx_dma_req;
- wire [UART_TOTAL-1:0] interrupts;
- // Different ways to generate interrupts.
- // assign local_int = interrupts[3:0];
- // assign ext_int_in = ~interrupts[7:4]; // External interrupts are active low.
- // assign gpio_int_in = interrupts[11:8];
- assign gpio_int_g0_in = interrupts[ 0+:UART_COUNT];
- assign gpio_int_g1_in = interrupts[UART_COUNT+:UART_COUNT];
- // Only 4 DMA requests are available. Can be used for any UART instance.
- assign ext_dma_DMACBREQ = { tx_dma_req[1:0], rx_dma_req[1:0] };
- assign { tx_dma_clr[1:0], rx_dma_clr[1:0] } = ext_dma_DMACCLR ;
- parameter APB_SEL_BITS = $clog2(UART_GROUP);
- parameter APB_ADDR_BITS = 12;
- parameter AHB_ADDR_BITS = APB_ADDR_BITS + APB_SEL_BITS;
- wire mem_apb_psel;
- wire mem_apb_penable;
- wire mem_apb_pwrite;
- wire [AHB_ADDR_BITS-1:0] mem_apb_paddr;
- wire [31:0] mem_apb_pwdata;
- wire [3:0] mem_apb_pstrb;
- wire [2:0] mem_apb_pprot;
- wire mem_apb_pready;
- wire mem_apb_pslverr;
- wire [31:0] mem_apb_prdata;
- wire [APB_ADDR_BITS-1:0] mem_apb_address = mem_apb_paddr[APB_ADDR_BITS-1:0];
- wire [UART_GROUP-1:0] mem_apb_onehot = 1'b1 << (mem_apb_paddr >> APB_ADDR_BITS);
- wire [UART_GROUP-1:0] uart_apb_psel;
- wire [UART_GROUP-1:0] uart_apb_penable;
- wire [UART_GROUP-1:0] uart_apb_pwrite;
- wire [UART_GROUP*APB_ADDR_BITS-1:0] uart_apb_paddr;
- wire [UART_GROUP*32-1:0] uart_apb_pwdata;
- wire [UART_GROUP*32-1:0] uart_apb_prdata;
- wire [UART_GROUP-1:0] uart_apb_pready;
- wire [UART_GROUP-1:0] uart_apb_pslverr = 0;
- ahb2apb #(AHB_ADDR_BITS) u_ahb2apb(
- .reset (!resetn ),
- .ahb_clock (sys_clock ),
- .ahb_hmastlock(1'b0 ),
- .ahb_htrans (mem_ahb_htrans ),
- .ahb_hsel (1'b1 ),
- .ahb_hready (mem_ahb_hready ),
- .ahb_hwrite (mem_ahb_hwrite ),
- .ahb_haddr (mem_ahb_haddr[AHB_ADDR_BITS-1:0]),
- .ahb_hsize (mem_ahb_hsize ),
- .ahb_hburst (mem_ahb_hburst ),
- .ahb_hprot (4'b0011 ),
- .ahb_hwdata (mem_ahb_hwdata ),
- .ahb_hrdata (mem_ahb_hrdata ),
- .ahb_hreadyout(mem_ahb_hreadyout ),
- .ahb_hresp (mem_ahb_hresp ),
- .apb_clock (bus_clock ),
- .apb_psel (mem_apb_psel ),
- .apb_penable (mem_apb_penable ),
- .apb_pwrite (mem_apb_pwrite ),
- .apb_paddr (mem_apb_paddr ),
- .apb_pwdata (mem_apb_pwdata ),
- .apb_pstrb (mem_apb_pstrb ),
- .apb_pprot (mem_apb_pprot ),
- .apb_pready (mem_apb_pready ),
- .apb_pslverr (mem_apb_pslverr ),
- .apb_prdata (mem_apb_prdata )
- );
- apb_mux #(UART_GROUP, APB_ADDR_BITS) u_apb_mux(
- .apb_clock (bus_clock ),
- .apb_resetn (resetn ),
- .apb_in_psel (mem_apb_psel ),
- .apb_in_penable (mem_apb_penable ),
- .apb_in_pwrite (mem_apb_pwrite ),
- .apb_in_paddr (mem_apb_address ),
- .apb_in_pwdata (mem_apb_pwdata ),
- .apb_in_prdata (mem_apb_prdata ),
- .apb_in_pready (mem_apb_pready ),
- .apb_in_pslverr (mem_apb_pslverr ),
- .apb_out_psel (uart_apb_psel ),
- .apb_out_penable(uart_apb_penable ),
- .apb_out_pwrite (uart_apb_pwrite ),
- .apb_out_paddr (uart_apb_paddr ),
- .apb_out_pwdata (uart_apb_pwdata ),
- .apb_out_prdata (uart_apb_prdata ),
- .apb_out_pready (uart_apb_pready ),
- .apb_out_pslverr(uart_apb_pslverr ),
- .apb_select (mem_apb_onehot )
- );
- multi_uart #(.CNT(UART_COUNT), .DATA_WIDTH(DATA_WIDTH), .FIFO_DEPTH(FIFO_DEPTH)) u_uart[UART_GROUP-1:0](
- .apb_clock (bus_clock ),
- .apb_resetn (resetn ),
- .apb_psel (uart_apb_psel ),
- .apb_penable(uart_apb_penable),
- .apb_pwrite (uart_apb_pwrite ),
- .apb_paddr (uart_apb_paddr ),
- .apb_pwdata (uart_apb_pwdata ),
- .apb_prdata (uart_apb_prdata ),
- .apb_pready (uart_apb_pready ),
- .uart_txd (uart_txd ),
- .uart_rxd (uart_rxd ),
- .tx_dma_clr (tx_dma_clr ),
- .tx_dma_req (tx_dma_req ),
- .rx_dma_clr (rx_dma_clr ),
- .rx_dma_req (rx_dma_req ),
- .interrupts (interrupts ),
- .uart_tx_busy(uart_tx_busy )
- );
- assign slave_ahb_hready = 1'b1;
- // 串口clk时钟1.5MHz(对应波特率4000)
- // 串口clk时钟15MHz (对应波特率40000)
- parameter SYSCLK_FREQ = 240_000_000;
- parameter SIMCLK_FREQ = 15_000_000;
- parameter SIM_CLK_PER = (SYSCLK_FREQ/SIMCLK_FREQ/2);
- reg [7:0] sim_clk_cnt;
- reg sim_clk_reg;
- always @(posedge sys_clock or negedge resetn) begin
- if (!resetn) begin
- sim_clk_cnt <= 8'h0;
- sim_clk_reg <= 8'h0;
- end else if (sim_clk_cnt < (SIM_CLK_PER - 1)) begin
- sim_clk_cnt <= sim_clk_cnt + 1'b1;
- end else begin
- sim_clk_reg <= !sim_clk_reg;
- sim_clk_cnt <= 8'h0;
- end
- end
- assign SIM_CLK = sim_clk_reg;
- endmodule
|