initial commit

This commit is contained in:
2026-04-12 22:20:18 +08:00
commit 190c2edbb2
155 changed files with 36314 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
module raminfr(clk, we, a, dpra, di, dpo);
parameter addr_width = 4;
parameter data_width = 8;
parameter depth = 16;
input clk;
input we;
input [addr_width-1:0] a;
input [addr_width-1:0] dpra;
input [data_width-1:0] di;
output [data_width-1:0] dpo;
reg [data_width-1:0] ram [depth-1:0];
wire [data_width-1:0] di;
wire [addr_width-1:0] a;
wire [addr_width-1:0] dpra;
always @(posedge clk) begin
if (we)
ram[a] <= di;
end
reg [data_width-1:0] dpo;
always @(posedge clk)
dpo <= ram[dpra];
endmodule

View File

@@ -0,0 +1,119 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`define UART_ADDR_WIDTH 3
`define UART_DATA_WIDTH 8
// Register addresses
`define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer
`define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter
`define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable
`define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification
`define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control
`define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control
`define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control
`define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status
`define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status
`define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register
`define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2)
`define UART_REG_DL2 `UART_ADDR_WIDTH'd1
// Interrupt Enable register bits
`define UART_IE_RDA 0 // Received Data available interrupt
`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt
`define UART_IE_RLS 2 // Receiver Line Status Interrupt
`define UART_IE_MS 3 // Modem Status Interrupt
// Interrupt Identification register bits
`define UART_II_IP 0 // Interrupt pending when 0
`define UART_II_II 3:1 // Interrupt identification
// Interrupt identification values for bits 3:1
`define UART_II_RLS 3'b011 // Receiver Line Status
`define UART_II_RDA 3'b010 // Receiver Data available
`define UART_II_TI 3'b110 // Timeout Indication
`define UART_II_THRE 3'b001 // Transmitter Holding Register empty
`define UART_II_MS 3'b000 // Modem Status
// FIFO Control Register bits
`define UART_FC_TL 1:0 // Trigger level
// FIFO trigger level values
`define UART_FC_1 2'b00
`define UART_FC_4 2'b01
`define UART_FC_8 2'b10
`define UART_FC_14 2'b11
// Line Control register bits
`define UART_LC_BITS 1:0 // bits in character
`define UART_LC_SB 2 // stop bits
`define UART_LC_PE 3 // parity enable
`define UART_LC_EP 4 // even parity
`define UART_LC_SP 5 // stick parity
`define UART_LC_BC 6 // Break control
`define UART_LC_DL 7 // Divisor Latch access bit
// Modem Control register bits
`define UART_MC_DTR 0
`define UART_MC_RTS 1
`define UART_MC_OUT1 2
`define UART_MC_OUT2 3
`define UART_MC_LB 4 // Loopback mode
// Line Status Register bits
`define UART_LS_DR 0 // Data ready
`define UART_LS_OE 1 // Overrun Error
`define UART_LS_PE 2 // Parity Error
`define UART_LS_FE 3 // Framing Error
`define UART_LS_BI 4 // Break interrupt
`define UART_LS_TFE 5 // Transmit FIFO is empty
`define UART_LS_TE 6 // Transmitter Empty indicator
`define UART_LS_EI 7 // Error indicator
// Modem Status Register bits
`define UART_MS_DCTS 0 // Delta signals
`define UART_MS_DDSR 1
`define UART_MS_TERI 2
`define UART_MS_DDCD 3
`define UART_MS_CCTS 4 // Complement signals
`define UART_MS_CDSR 5
`define UART_MS_CRI 6
`define UART_MS_CDCD 7
// FIFO parameter defines
`define UART_FIFO_WIDTH 8
`define UART_FIFO_DEPTH 16
`define UART_FIFO_POINTER_W 4
`define UART_FIFO_COUNTER_W 5
`define UART_FIFO_REC_WIDTH 11

View File

@@ -0,0 +1,288 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "uart_defines.h"
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable,
counter_t, rf_count, rf_data_out, rf_error_bit,
rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
input clk;
input wb_rst_i;
input [7:0] lcr;
input rf_pop;
input srx_pad_i;
input enable;
input rx_reset;
input lsr_mask;
output [9:0] counter_t;
output [`UART_FIFO_COUNTER_W-1:0] rf_count;
output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
output rf_overrun;
output rf_error_bit;
output [3:0] rstate;
output rf_push_pulse;
reg [3:0] rstate;
reg [3:0] rcounter16;
reg [2:0] rbit_counter;
reg [7:0] rshift;
reg rparity;
reg rparity_error;
reg rframing_error;
reg rbit_in;
reg rparity_xor;
reg [7:0] counter_b;
reg rf_push_q;
reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in;
wire[`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_push_pulse;
reg rf_push;
wire rf_pop;
wire rf_overrun;
wire[`UART_FIFO_COUNTER_W-1:0] rf_count;
wire rf_error_bit;
wire break_error = (counter_b == 0);
uart_rfifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
.clk ( clk ),
.wb_rst_i ( wb_rst_i ),
.data_in ( rf_data_in ),
.data_out ( rf_data_out ),
.push ( rf_push_pulse),
.pop ( rf_pop ),
.overrun ( rf_overrun ),
.count ( rf_count ),
.error_bit ( rf_error_bit ),
.fifo_reset ( rx_reset ),
.reset_status( lsr_mask )
);
wire rcounter16_eq_7 = (rcounter16 == 4'd7);
wire rcounter16_eq_0 = (rcounter16 == 4'd0);
wire rcounter16_eq_1 = (rcounter16 == 4'd1);
wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
parameter sr_idle = 4'd0;
parameter sr_rec_start = 4'd1;
parameter sr_rec_bit = 4'd2;
parameter sr_rec_parity = 4'd3;
parameter sr_rec_stop = 4'd4;
parameter sr_check_parity = 4'd5;
parameter sr_rec_prepare = 4'd6;
parameter sr_end_bit = 4'd7;
parameter sr_ca_lc_parity = 4'd8;
parameter sr_wait1 = 4'd9;
parameter sr_push = 4'd10;
always @(posedge clk ) begin
if (wb_rst_i) begin
rstate <= sr_idle;
rbit_in <= 1'b0;
rcounter16 <= 0;
rbit_counter <= 0;
rparity_xor <= 1'b0;
rframing_error <= 1'b0;
rparity_error <= 1'b0;
rparity <= 1'b0;
rshift <= 0;
rf_push <= 1'b0;
rf_data_in <= 0;
end
else if (enable) begin
case (rstate)
sr_idle : begin
rf_push <= 1'b0;
rf_data_in <= 0;
rcounter16 <= 4'b1110;
if (srx_pad_i==1'b0 & ~break_error) begin
rstate <= sr_rec_start;
end
end
sr_rec_start : begin
rf_push <= 1'b0;
if (rcounter16_eq_7)
if (srx_pad_i==1'b1)
rstate <= sr_idle;
else
rstate <= sr_rec_prepare;
else rstate<=rstate;
rcounter16 <= rcounter16_minus_1;
end
sr_rec_prepare: begin
case (lcr[1:0])
2'b00 : rbit_counter <= 3'b100;
2'b01 : rbit_counter <= 3'b101;
2'b10 : rbit_counter <= 3'b110;
2'b11 : rbit_counter <= 3'b111;
endcase
if (rcounter16_eq_0) begin
rstate <= sr_rec_bit;
rcounter16 <= 4'b1110;
rshift <= 0;
end
else
rstate <= sr_rec_prepare;
rcounter16 <= rcounter16_minus_1;
end
sr_rec_bit : begin
if (rcounter16_eq_0) rstate <= sr_end_bit;
if (rcounter16_eq_7)
case (lcr[1:0])
2'b00 : rshift[4:0] <= {srx_pad_i, rshift[4:1]};
2'b01 : rshift[5:0] <= {srx_pad_i, rshift[5:1]};
2'b10 : rshift[6:0] <= {srx_pad_i, rshift[6:1]};
2'b11 : rshift[7:0] <= {srx_pad_i, rshift[7:1]};
endcase
rcounter16 <= rcounter16_minus_1;
end
sr_end_bit : begin
if (rbit_counter==3'b0)
if (lcr[`UART_LC_PE])
rstate <= sr_rec_parity;
else begin
rstate <= sr_rec_stop;
rparity_error<= 1'b0;
end
else begin
rstate <= sr_rec_bit;
rbit_counter <= rbit_counter - 1'b1;
end
rcounter16 <= 4'b1110;
end
sr_rec_parity : begin
if (rcounter16_eq_7) begin
rparity <= srx_pad_i;
rstate <= sr_ca_lc_parity;
end
rcounter16 <= rcounter16_minus_1;
end
sr_ca_lc_parity:begin
rcounter16 <= rcounter16_minus_1;
rparity_xor <= ^{rshift,rparity};
rstate <= sr_check_parity;
end
sr_check_parity: begin
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
2'b00: rparity_error <= rparity_xor == 0;
2'b01: rparity_error <= ~rparity;
2'b10: rparity_error <= rparity_xor == 1;
2'b11: rparity_error <= rparity;
endcase
rcounter16 <= rcounter16_minus_1;
rstate <= sr_wait1;
end
sr_wait1 :
if (rcounter16_eq_0) begin
rstate <= sr_rec_stop;
rcounter16 <= 4'b1110;
end
else rcounter16 <= rcounter16_minus_1;
sr_rec_stop : begin
if (rcounter16_eq_7) begin
rframing_error <= !srx_pad_i;
rstate <= sr_push;
end
rcounter16 <= rcounter16_minus_1;
end
sr_push : begin
if(srx_pad_i | break_error) begin
if(break_error)
rf_data_in <= {8'b0, 3'b100};
else
rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
rf_push <= 1'b1;
rstate <= sr_idle;
end
else if(~rframing_error) begin
rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
rf_push <= 1'b1;
rcounter16 <= 4'b1110;
rstate <= sr_rec_start;
end
end
default : rstate <= sr_idle;
endcase
end
end
always @ (posedge clk ) begin
if(wb_rst_i) rf_push_q <= 0;
else rf_push_q <= rf_push;
end
assign rf_push_pulse = rf_push & ~rf_push_q;
reg [9:0] toc_value;
always @(lcr)
case (lcr[3:0])
4'b0000 : toc_value = 447;
4'b0100 : toc_value = 479;
4'b0001, 4'b1000 : toc_value = 511;
4'b1100 : toc_value = 543;
4'b0010, 4'b0101, 4'b1001 : toc_value = 575;
4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639;
4'b0111, 4'b1011, 4'b1110 : toc_value = 703;
4'b1111 : toc_value = 767;
endcase
wire [7:0] brc_value;
assign brc_value = toc_value[9:2];
always @(posedge clk ) begin
if (wb_rst_i) counter_b <= 8'd159;
else if (srx_pad_i) counter_b <= brc_value;
else if (enable & counter_b != 8'b0)
counter_b <= counter_b - 1;
end
reg [9:0] counter_t;
always @(posedge clk ) begin
if (wb_rst_i) counter_t <= 10'd639;
else if(rf_push_pulse || rf_pop || rf_count == 0)
counter_t <= toc_value;
else if (enable && counter_t != 10'b0)
counter_t <= counter_t - 1;
end
endmodule

View File

@@ -0,0 +1,711 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "uart_defines.h"
`define UART_DL1 7:0
`define UART_DL2 15:8
`define UART_DL3 23:16
module uart_regs (clk, rst, clk_carrier,
addr, dat_i, dat_o, we, re,
modem_inputs,
rts_pad_o, dtr_pad_o,
stx_pad_o,TXD_i,srx_pad_i,RXD_o,
int_o,
usart_mode,
rx_en,
tx2rx_en
);
input clk;
input rst ;
input clk_carrier;
input [2:0] addr;
input [7:0] dat_i;
output [7:0] dat_o;
input we;
input re;
output stx_pad_o;
input srx_pad_i;
input TXD_i;
output RXD_o;
input [3:0] modem_inputs;
output rts_pad_o;
output dtr_pad_o;
output int_o;
output usart_mode;
output tx2rx_en;
output rx_en;
wire [3:0] modem_inputs;
reg enable;
wire stx_pad_o;
wire srx_pad_i;
wire srx_pad;
reg [7:0] dat_o;
wire [2:0] addr;
wire [7:0] dat_i;
reg [3:0] ier;
reg [3:0] iir;
reg [1:0] fcr;
reg [4:0] mcr;
reg infrared;
reg rx_pol;
reg [7:0] lcr;
reg [7:0] msr;
reg [23:0] dl;
reg start_dlc;
reg lsr_mask_d;
reg msi_reset;
reg [15:0] dlc;
reg int_o;
reg [3:0] trigger_level;
reg rx_reset;
reg tx_reset;
wire dlab;
wire usart_mode;
wire usart_rx_en;
wire usart_tx_en;
wire tx2rx_en;
reg sclk_reg;
reg sclk_en_reg;
reg [7:0] mode_reg;
reg [7:0] fi_di_reg;
reg [7:0] sclk_count;
reg [2:0] repeat_reg;
wire usart_normal;
wire usart_irda;
wire usart_t0;
wire usart_t1;
wire rx_en;
wire tx_en;
wire sclk_por;
assign usart_normal = mode_reg[1:0]==2'h0;
assign usart_irda = mode_reg[1:0]==2'h1;
assign usart_t0 = mode_reg[1:0]==2'h2;
assign usart_t1 = mode_reg[1:0]==2'h3;
assign usart_tx_en = mode_reg[2]==1'b0;
assign usart_rx_en = mode_reg[2]==1'b1;
assign sclk_por = mode_reg[3];
assign RXD_o = sclk_reg^sclk_por;
assign usart_mode = usart_t0 || usart_t1;
assign rx_en = usart_normal || usart_irda || usart_mode && usart_rx_en;
assign tx_en = usart_normal || usart_irda || usart_mode && usart_tx_en;
always @(posedge clk )
begin
if (rst) begin
mode_reg <= 8'h0;
fi_di_reg <= 8'h0;
repeat_reg<= 3'h4;
sclk_en_reg<= 1'b0;
end
else if (we && addr==`UART_REG_SR)begin
if(dlab)
fi_di_reg <= dat_i;
else
mode_reg <= dat_i;
end
else begin
if(enable) sclk_en_reg <= mode_reg[4];
repeat_reg <= mode_reg[7:5];
end
end
always @(posedge clk)
begin
if(rst) begin
sclk_count <= 8'b0;
sclk_reg <=1'b0;
end
else if(usart_mode&&(fi_di_reg>8'h1)&&sclk_en_reg) begin
if(sclk_count == fi_di_reg[7:1]) begin
sclk_reg <= 1'b1;
sclk_count <= sclk_count + 1'b1;
end
else if(sclk_count == fi_di_reg) begin
sclk_reg <= 1'b0;
sclk_count <= 8'b0;
end
else begin
sclk_count <= sclk_count + 1'b1;
end
end
else begin
sclk_reg <=1'b0;
sclk_count <= 8'b0;
end
end
wire cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i;
wire loopback;
wire cts, dsr, ri, dcd;
wire cts_c, dsr_c, ri_c, dcd_c;
wire rts_pad_o, dtr_pad_o;
wire [7:0] lsr;
wire lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
reg lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
wire lsr_mask;
assign lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
assign {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
assign {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
: {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
assign dlab = lcr[`UART_LC_DL];
assign loopback = mcr[4];
assign rts_pad_o = mcr[`UART_MC_RTS];
assign dtr_pad_o = mcr[`UART_MC_DTR];
wire rls_int;
wire rda_int;
wire ti_int;
wire thre_int;
wire ms_int;
wire tf_push;
reg rf_pop;
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_error_bit;
wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
wire [2:0] tstate;
wire [3:0] rstate;
wire [9:0] counter_t;
wire thre_set_en;
reg [7:0] block_cnt;
reg [7:0] block_value;
wire current_finish;
wire max_repeat_time;
wire serial_out;
wire serial_out_modulated = ~ (clk_carrier & serial_out);
uart_transmitter transmitter(.clk(clk), .wb_rst_i(rst), .lcr(lcr), .tf_push(tf_push), .wb_dat_i(dat_i),
.tx2rx_en (tx2rx_en),
.usart_mode(usart_mode),
.srx_pad_i(TXD_i),
.enable (enable && tx_en),
.usart_t0(usart_t0),
.repeat_time(repeat_reg ),
.current_finish(current_finish),
.max_repeat_time(max_repeat_time),
.stx_pad_o(serial_out), .tstate(tstate), .tf_count(tf_count),
.tx_reset(tx_reset), .lsr_mask(lsr_mask));
wire rcv_pad_i;
assign rcv_pad_i = ~usart_mode ? srx_pad_i : (rx_en ? TXD_i : 1'b1);
uart_sync_flops i_uart_sync_flops(
.rst_i (rst),
.clk_i (clk),
.stage1_rst_i (1'b0),
.stage1_clk_en_i (1'b1),
.async_dat_i (rcv_pad_i),
.sync_dat_o (srx_pad)
);
defparam i_uart_sync_flops.width = 1;
defparam i_uart_sync_flops.init_value = 1'b1;
wire serial_in = loopback ? serial_out : rx_pol ? ~srx_pad : srx_pad;
assign stx_pad_o = loopback ? 1'b1 : infrared ? serial_out_modulated : serial_out;
wire rf_overrun;
wire rf_push_pulse;
uart_receiver receiver(.clk(clk), .wb_rst_i(rst), .lcr(lcr), .rf_pop(rf_pop), .srx_pad_i(serial_in),
.enable(enable && rx_en),
.counter_t(counter_t), .rf_count(rf_count), .rf_data_out(rf_data_out), .rf_error_bit(rf_error_bit),
.rf_overrun(rf_overrun), .rx_reset(rx_reset), .lsr_mask(lsr_mask), .rstate(rstate), .rf_push_pulse(rf_push_pulse));
always @(dl or dlab or ier or iir or fi_di_reg or mode_reg
or lcr or lsr or msr or rf_data_out or addr )
begin
case (addr)
`UART_REG_RB : dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
`UART_REG_IE : dat_o = dlab ? dl[`UART_DL2] : ier;
`UART_REG_II : dat_o = dlab ? dl[`UART_DL3] : {4'b1100,iir};
`UART_REG_LC : dat_o = lcr;
`UART_REG_LS : dat_o = lsr;
`UART_REG_MS : dat_o = msr;
`UART_REG_SR : dat_o = dlab ? fi_di_reg : mode_reg;
default : dat_o = 8'b0;
endcase
end
always @(posedge clk )
begin
if (rst)
rf_pop <= 0;
else
if (rf_pop)
rf_pop <= 0;
else
if (re && addr == `UART_REG_RB && !dlab)
rf_pop <= 1;
end
wire lsr_mask_condition;
wire iir_read;
wire msr_read;
wire fifo_read;
wire fifo_write;
assign lsr_mask_condition = (re && addr == `UART_REG_LS && !dlab);
assign iir_read = (re && addr == `UART_REG_II && !dlab);
assign msr_read = (re && addr == `UART_REG_MS && !dlab);
assign fifo_read = (re && addr == `UART_REG_RB && !dlab);
assign fifo_write = (we && addr == `UART_REG_TR && !dlab);
always @(posedge clk )
begin
if (rst)
lsr_mask_d <= 0;
else
lsr_mask_d <= lsr_mask_condition;
end
assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
always @(posedge clk )
begin
if (rst)
msi_reset <= 1;
else
if (msi_reset)
msi_reset <= 0;
else
if (msr_read)
msi_reset <= 1;
end
always @(posedge clk )
if (rst)
lcr <= 8'b00000011;
else
if (we && addr==`UART_REG_LC)
lcr <= dat_i;
always @(posedge clk )
if (rst)
begin
ier <= 4'b0000;
dl[`UART_DL2] <= 8'b0;
end
else
if (we && addr==`UART_REG_IE)
if (dlab)
begin
dl[`UART_DL2] <= dat_i;
end
else
ier <= dat_i[3:0];
else
ier<= ier;
always @(posedge clk )
if (rst) begin
fcr <= 2'b11;
rx_reset <= 0;
tx_reset <= 0;
dl[`UART_DL3] <= 8'h0;
end else
if (we && addr==`UART_REG_FC) begin
if(dlab) dl[`UART_DL3] <= dat_i;
else begin
fcr <= dat_i[7:6];
rx_reset <= dat_i[1];
tx_reset <= dat_i[2];
end
end else begin
rx_reset <= 0;
tx_reset <= 0;
end
always @(posedge clk )
if (rst) begin
mcr <= 5'b0;
infrared <= 1'b0;
rx_pol <= 1'b0; end
else
if(we && addr==`UART_REG_MC) begin
mcr <= dat_i[4:0];
infrared <= dat_i[7];
rx_pol <= dat_i[6]; end
assign tf_push = we & addr==`UART_REG_TR & !dlab;
always @(posedge clk )
if (rst)
begin
dl[`UART_DL1] <= 8'b0;
start_dlc <= 1'b0;
end
else
if (we && addr==`UART_REG_TR)
if (dlab)
begin
dl[`UART_DL1] <= dat_i;
start_dlc <= 1'b1;
end
else
begin
start_dlc <= 1'b0;
end
else
begin
start_dlc <= 1'b0;
end
always @(fcr)
case (fcr[`UART_FC_TL])
2'b00 : trigger_level = 1;
2'b01 : trigger_level = 4;
2'b10 : trigger_level = 8;
2'b11 : trigger_level = 14;
endcase
reg [3:0] delayed_modem_signals;
always @(posedge clk )
begin
if (rst)
begin
msr <= 0;
delayed_modem_signals[3:0] <= 0;
end
else begin
msr[`UART_MS_DDCD:`UART_MS_DCTS] <= msi_reset ? 4'b0 :
msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
msr[`UART_MS_CDCD:`UART_MS_CCTS] <= {dcd_c, ri_c, dsr_c, cts_c};
delayed_modem_signals[3:0] <= {dcd, ri, dsr, cts};
end
end
assign lsr0 = (rf_count==0 && rf_push_pulse);
assign lsr1 = rf_overrun;
assign lsr2 = rf_data_out[1];
assign lsr3 = rf_data_out[0];
assign lsr4 = rf_data_out[2];
assign lsr5 = current_finish && (tf_count==5'b0 && thre_set_en);
assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == 3'd0));
assign lsr7 = rf_error_bit | rf_overrun;
reg lsr0_d;
always @(posedge clk )
if (rst) lsr0_d <= 0;
else lsr0_d <= lsr0;
always @(posedge clk )
if (rst) lsr0r <= 0;
else lsr0r <= (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 :
lsr0r || (lsr0 && ~lsr0_d);
reg lsr1_d;
always @(posedge clk )
if (rst) lsr1_d <= 0;
else lsr1_d <= lsr1;
always @(posedge clk )
if (rst) lsr1r <= 0;
else lsr1r <= lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d);
reg lsr2_d;
always @(posedge clk )
if (rst) lsr2_d <= 0;
else lsr2_d <= lsr2;
always @(posedge clk )
if (rst) lsr2r <= 0;
else lsr2r <= lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d);
reg lsr3_d;
always @(posedge clk )
if (rst) lsr3_d <= 0;
else lsr3_d <= lsr3;
always @(posedge clk )
if (rst) lsr3r <= 0;
else lsr3r <= lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d);
reg lsr4_d;
always @(posedge clk )
if (rst) lsr4_d <= 0;
else lsr4_d <= lsr4;
always @(posedge clk )
if (rst) lsr4r <= 0;
else lsr4r <= lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
reg lsr5_d;
always @(posedge clk )
if (rst) lsr5_d <= 1;
else lsr5_d <= lsr5;
always @(posedge clk )
if (rst) lsr5r <= 1;
else lsr5r <= (fifo_write) ? 0 : lsr5r || (lsr5 && ~lsr5_d);
reg lsr6_d;
always @(posedge clk )
if (rst) lsr6_d <= 1;
else lsr6_d <= lsr6;
always @(posedge clk )
if (rst) lsr6r <= 1;
else lsr6r <= (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
reg lsr7_d;
always @(posedge clk )
if (rst) lsr7_d <= 0;
else lsr7_d <= lsr7;
always @(posedge clk )
if (rst) lsr7r <= 0;
else lsr7r <= lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
reg [8:0] M_cnt;
wire [8:0] M_next = M_cnt + dl[`UART_DL3];
wire M_toggle = M_cnt[8] ^ M_next[8];
always @(posedge clk )
begin
if (rst) begin
dlc <= 0;
M_cnt <= 8'h0;
end
else if (start_dlc | ~ (|dlc)) begin
dlc <= dl - 1 + M_toggle;
M_cnt <= M_next;
end
else
dlc <= dlc - 1;
end
always @(posedge clk )
begin
if (rst)
enable <= 1'b0;
else if (|dl & ~(|dlc))
enable <= 1'b1;
else
enable <= 1'b0;
end
always @(lcr)
case (lcr[3:0])
4'b0000 : block_value = 95;
4'b0100 : block_value = 103;
4'b0001, 4'b1000 : block_value = 111;
4'b1100 : block_value = 119;
4'b0010, 4'b0101, 4'b1001 : block_value = 127;
4'b0011, 4'b0110, 4'b1010, 4'b1101 : block_value = 143;
4'b0111, 4'b1011, 4'b1110 : block_value = 159;
4'b1111 : block_value = 175;
endcase
always @(posedge clk )
begin
if (rst)
block_cnt <= 8'd0;
else
if(lsr5r & fifo_write)
block_cnt <= usart_t0 ? (block_value + 8'h16) : block_value;
else
if (enable & block_cnt != 8'b0)
block_cnt <= block_cnt - 1;
end
assign thre_set_en = ~(|block_cnt);
assign rls_int = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
assign rda_int = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
assign thre_int = ier[`UART_IE_THRE]&& lsr[`UART_LS_TFE];
assign ms_int = ier[`UART_IE_MS] && (usart_t0 ? max_repeat_time : (| msr[3:0]));
assign ti_int = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
reg rls_int_d;
reg thre_int_d;
reg ms_int_d;
reg ti_int_d;
reg rda_int_d;
always @(posedge clk )
if (rst) rls_int_d <= 0;
else rls_int_d <= rls_int;
always @(posedge clk )
if (rst) rda_int_d <= 0;
else rda_int_d <= rda_int;
always @(posedge clk )
if (rst) thre_int_d <= 0;
else thre_int_d <= thre_int;
always @(posedge clk )
if (rst) ms_int_d <= 0;
else ms_int_d <= ms_int;
always @(posedge clk )
if (rst) ti_int_d <= 0;
else ti_int_d <= ti_int;
wire rls_int_rise;
wire thre_int_rise;
wire ms_int_rise;
wire ti_int_rise;
wire rda_int_rise;
assign rda_int_rise = rda_int & ~rda_int_d;
assign rls_int_rise = rls_int & ~rls_int_d;
assign thre_int_rise = thre_int & ~thre_int_d;
assign ms_int_rise = ms_int & ~ms_int_d;
assign ti_int_rise = ti_int & ~ti_int_d;
reg rls_int_pnd;
reg rda_int_pnd;
reg thre_int_pnd;
reg ms_int_pnd;
reg ti_int_pnd;
always @(posedge clk )
if (rst) rls_int_pnd <= 0;
else
rls_int_pnd <= lsr_mask ? 0 :
rls_int_rise ? 1 :
rls_int_pnd && ier[`UART_IE_RLS];
reg d1_fifo_read;
always @( posedge clk ) d1_fifo_read <= fifo_read;
always @(posedge clk)
if (rst) rda_int_pnd <= 0;
else rda_int_pnd <= ((rf_count == {1'b0,trigger_level}) && d1_fifo_read) ? 0 :
rda_int_rise ? 1 :
rda_int_pnd && ier[`UART_IE_RDA];
always @(posedge clk )
if (rst) thre_int_pnd <= 0;
else
thre_int_pnd <= fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
thre_int_rise ? 1 :
thre_int_pnd && ier[`UART_IE_THRE];
always @(posedge clk )
if (rst) ms_int_pnd <= 0;
else
ms_int_pnd <= msr_read ? 0 : ms_int_rise ? 1 :
ms_int_pnd && ier[`UART_IE_MS];
always @(posedge clk )
if (rst) ti_int_pnd <= 0;
else
ti_int_pnd <= fifo_read ? 0 : ti_int_rise ? 1 :
ti_int_pnd && ier[`UART_IE_RDA];
always @(posedge clk )
begin
if (rst) int_o <= 1'b0;
else int_o <= rls_int_pnd ? ~lsr_mask :
rda_int_pnd ? 1 :
ti_int_pnd ? ~fifo_read:
thre_int_pnd? !(fifo_write & iir_read) :
ms_int_pnd ? ~msr_read :
0;
end
always @(posedge clk )
begin
if (rst)
iir <= 1;
else
if (rls_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_RLS;
iir[`UART_II_IP] <= 1'b0;
end else
if (rda_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_RDA;
iir[`UART_II_IP] <= 1'b0;
end
else if (ti_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_TI;
iir[`UART_II_IP] <= 1'b0;
end
else if (thre_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_THRE;
iir[`UART_II_IP] <= 1'b0;
end
else if (ms_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_MS;
iir[`UART_II_IP] <= 1'b0;
end else
begin
iir[`UART_II_II] <= 0;
iir[`UART_II_IP] <= 1'b1;
end
end
endmodule

View File

@@ -0,0 +1,193 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "uart_defines.h"
module uart_rfifo (clk,
wb_rst_i, data_in, data_out,
push,
pop,
overrun,
count,
error_bit,
fifo_reset,
reset_status
);
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
input clk;
input wb_rst_i;
input push;
input pop;
input [fifo_width-1:0] data_in;
input fifo_reset;
input reset_status;
output [fifo_width-1:0] data_out;
output overrun;
output [fifo_counter_w-1:0] count;
output error_bit;
wire [fifo_width-1:0] data_out;
wire [7:0] data8_out;
reg [2:0] fifo[fifo_depth-1:0];
reg [fifo_pointer_w-1:0] top;
reg [fifo_pointer_w-1:0] bottom;
reg [fifo_counter_w-1:0] count;
reg overrun;
wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
raminfr #(fifo_pointer_w,8,fifo_depth) rfifo (.clk(clk),
.we(push),
.a(top),
.dpra(bottom),
.di(data_in[fifo_width-1:fifo_width-8]),
.dpo(data8_out)
);
always @(posedge clk)
begin
if (wb_rst_i)
begin
top <= 0;
bottom <= 1'b0;
count <= 0;
fifo[0] <= 0;
fifo[1] <= 0;
fifo[2] <= 0;
fifo[3] <= 0;
fifo[4] <= 0;
fifo[5] <= 0;
fifo[6] <= 0;
fifo[7] <= 0;
fifo[8] <= 0;
fifo[9] <= 0;
fifo[10]<= 0;
fifo[11]<= 0;
fifo[12]<= 0;
fifo[13]<= 0;
fifo[14]<= 0;
fifo[15]<= 0;
end
else
if (fifo_reset) begin
top <= 0;
bottom <= 1'b0;
count <= 0;
fifo[0] <= 0;
fifo[1] <= 0;
fifo[2] <= 0;
fifo[3] <= 0;
fifo[4] <= 0;
fifo[5] <= 0;
fifo[6] <= 0;
fifo[7] <= 0;
fifo[8] <= 0;
fifo[9] <= 0;
fifo[10]<= 0;
fifo[11]<= 0;
fifo[12]<= 0;
fifo[13]<= 0;
fifo[14]<= 0;
fifo[15]<= 0;
end
else
begin
case ({push, pop})
2'b10 : if (count<fifo_depth)
begin
top <= top_plus_1;
fifo[top] <= data_in[2:0];
count <= count + 1'b1;
end
2'b01 : if(count>0)
begin
fifo[bottom] <= 0;
bottom <= bottom + 1'b1;
count <= count - 1'b1;
end
2'b11 : begin
bottom <= bottom + 1'b1;
top <= top_plus_1;
fifo[top] <= data_in[2:0];
end
default: ;
endcase
end
end
always @(posedge clk)
begin
if (wb_rst_i)
overrun <= 1'b0;
else
if(fifo_reset | reset_status)
overrun <= 1'b0;
else
if(push & ~pop & (count==fifo_depth))
overrun <= 1'b1;
end
assign data_out = {data8_out,fifo[bottom]};
wire [2:0] word0 = fifo[0];
wire [2:0] word1 = fifo[1];
wire [2:0] word2 = fifo[2];
wire [2:0] word3 = fifo[3];
wire [2:0] word4 = fifo[4];
wire [2:0] word5 = fifo[5];
wire [2:0] word6 = fifo[6];
wire [2:0] word7 = fifo[7];
wire [2:0] word8 = fifo[8];
wire [2:0] word9 = fifo[9];
wire [2:0] word10 = fifo[10];
wire [2:0] word11 = fifo[11];
wire [2:0] word12 = fifo[12];
wire [2:0] word13 = fifo[13];
wire [2:0] word14 = fifo[14];
wire [2:0] word15 = fifo[15];
assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] |
word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] |
word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] |
word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
endmodule

View File

@@ -0,0 +1,76 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
module uart_sync_flops
(
rst_i,
clk_i,
stage1_rst_i,
stage1_clk_en_i,
async_dat_i,
sync_dat_o
);
parameter Tp = 1;
parameter width = 1;
parameter init_value = 1'b0;
input rst_i;
input clk_i;
input stage1_rst_i;
input stage1_clk_en_i;
input [width-1:0] async_dat_i;
output [width-1:0] sync_dat_o;
reg [width-1:0] sync_dat_o;
reg [width-1:0] flop_0;
always @ (posedge clk_i)
begin
if (rst_i)
flop_0 <= {width{init_value}};
else
flop_0 <= async_dat_i;
end
always @ (posedge clk_i)
begin
if (rst_i)
sync_dat_o <= {width{init_value}};
else if (stage1_rst_i)
sync_dat_o <= {width{init_value}};
else if (stage1_clk_en_i)
sync_dat_o <= flop_0;
end
endmodule

View File

@@ -0,0 +1,129 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "uart_defines.h"
module uart_tfifo (clk,
wb_rst_i, data_in, data_out,
push,
pop,
overrun,
count,
fifo_reset,
reset_status
);
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
input clk;
input wb_rst_i;
input push;
input pop;
input [fifo_width-1:0] data_in;
input fifo_reset;
input reset_status;
output [fifo_width-1:0] data_out;
output overrun;
output [fifo_counter_w-1:0] count;
wire [fifo_width-1:0] data_out;
reg [fifo_pointer_w-1:0] top;
reg [fifo_pointer_w-1:0] bottom;
reg [fifo_counter_w-1:0] count;
reg overrun;
wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo (.clk(clk),
.we(push),
.a(top),
.dpra(bottom),
.di(data_in),
.dpo(data_out)
);
always @(posedge clk)
begin
if (wb_rst_i)
begin
top <= 0;
bottom <= 1'b0;
count <= 0;
end
else
if (fifo_reset) begin
top <= 0;
bottom <= 1'b0;
count <= 0;
end
else
begin
case ({push, pop})
2'b10 : if (count<fifo_depth)
begin
top <= top_plus_1;
count <= count + 1'b1;
end
2'b01 : if(count>0)
begin
bottom <= bottom + 1'b1;
count <= count - 1'b1;
end
2'b11 : begin
bottom <= bottom + 1'b1;
top <= top_plus_1;
end
default: ;
endcase
end
end
always @(posedge clk)
begin
if (wb_rst_i)
overrun <= 1'b0;
else
if(fifo_reset | reset_status)
overrun <= 1'b0;
else
if(push & (count==fifo_depth))
overrun <= 1'b1;
end
endmodule

View File

@@ -0,0 +1,107 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "uart_defines.h"
module UART_TOP(
PCLK, PRST_,
PSEL, PENABLE, PADDR, PWRITE,
PWDATA, URT_PRDATA,
INT, clk_carrier,
TXD_i, TXD_o, TXD_oe,
RXD_i, RXD_o, RXD_oe,
RTS, CTS, DSR,
DCD, DTR, RI
);
input PCLK, PRST_;
input PSEL, PENABLE, PWRITE;
input [7:0] PADDR;
input [7:0] PWDATA;
output [7:0] URT_PRDATA;
output INT;
input clk_carrier;
input TXD_i;
output TXD_o;
output TXD_oe;
input RXD_i;
output RXD_o;
output RXD_oe;
output RTS;
input CTS, DSR, DCD;
output DTR;
input RI;
wire prst = !PRST_;
wire we = PSEL & PENABLE & PWRITE;
wire re = PSEL & PENABLE & !PWRITE;
wire rx_en;
wire tx2rx_en;
wire isomode;
assign TXD_oe = isomode&&(rx_en||tx2rx_en) ? 1'b1:1'b0;
assign RXD_oe =~isomode;
uart_regs regs(
.clk (PCLK ),
.rst (prst ),
.clk_carrier (clk_carrier),
.addr (PADDR[2:0] ),
.dat_i (PWDATA ),
.dat_o (URT_PRDATA ),
.we (we ),
.re (re ),
.modem_inputs({ CTS, DSR, RI, DCD } ),
.rts_pad_o (RTS ),
.dtr_pad_o (DTR ),
.stx_pad_o (TXD_o ),
.TXD_i (TXD_i ),
.srx_pad_i (RXD_i ),
.RXD_o (RXD_o ),
.int_o ( INT ),
.tx2rx_en (tx2rx_en ),
.rx_en (rx_en ),
.usart_mode (isomode )
);
endmodule

View File

@@ -0,0 +1,281 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "uart_defines.h"
module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i,
enable,stx_pad_o, tstate, tf_count, tx_reset, lsr_mask,
usart_t0,srx_pad_i,repeat_time,max_repeat_time,current_finish,
usart_mode,tx2rx_en);
input clk;
input wb_rst_i;
input [7:0] lcr;
input tf_push;
input [7:0] wb_dat_i;
input enable;
input tx_reset;
input lsr_mask;
input usart_mode;
input usart_t0,srx_pad_i;
input [2:0] repeat_time;
output current_finish;
output max_repeat_time;
output tx2rx_en;
reg tx2rx_en;
output stx_pad_o;
output [2:0] tstate;
output [`UART_FIFO_COUNTER_W-1:0] tf_count;
reg [2:0] tstate;
reg [4:0] counter;
reg [2:0] bit_counter;
reg [6:0] shift_out;
reg stx_o_tmp;
reg parity_xor;
reg tf_pop;
reg bit_out;
reg tx_error;
reg [2:0] error_time;
wire [`UART_FIFO_WIDTH-1:0] tf_data_in;
wire [`UART_FIFO_WIDTH-1:0] tf_data_out;
wire tf_push;
wire tf_overrun;
wire [`UART_FIFO_COUNTER_W-1:0]tf_count;
assign tf_data_in = wb_dat_i;
uart_tfifo fifo_tx(
.clk ( clk ),
.wb_rst_i( wb_rst_i ),
.data_in ( tf_data_in ),
.data_out( tf_data_out ),
.push ( tf_push ),
.pop ( tf_pop ),
.overrun ( tf_overrun ),
.count ( tf_count ),
.fifo_reset ( tx_reset),
.reset_status(lsr_mask )
);
parameter s_idle = 3'd0;
parameter s_send_start = 3'd1;
parameter s_send_byte = 3'd2;
parameter s_send_parity = 3'd3;
parameter s_send_stop = 3'd4;
parameter s_pop_byte = 3'd5;
parameter s_send_guard1 = 3'd6;
reg [7:0]tf_data_bak;
wire max_repeat_time = (error_time==(repeat_time+1'b1)) & usart_mode & usart_t0;
always @(posedge clk )
begin
if (wb_rst_i)
begin
tx_error <= 1'b0;
error_time <= 3'b0;
tstate <= s_idle;
stx_o_tmp <= 1'b1;
counter <= 5'b0;
shift_out <= 7'b0;
bit_out <= 1'b0;
parity_xor <= 1'b0;
tf_pop <= 1'b0;
bit_counter <= 3'b0;
tx2rx_en <= 1'b0;
tf_data_bak <= 8'h0;
end
else
if (enable)
begin
case (tstate)
s_idle :if ((~|tf_count)&(error_time==(repeat_time+1'b1)||~tx_error||~usart_mode))
begin
tstate <= s_idle;
stx_o_tmp <= 1'b1;
tx_error <= 1'b0;
end
else begin
tf_pop <= 1'b0;
stx_o_tmp <= 1'b1;
tstate <= s_pop_byte;
end
s_pop_byte : begin
if(tx_error&(error_time !=(repeat_time+1'b1)))
begin
tf_pop <= 1'b0;
case (lcr[1:0])
2'b00 : begin
bit_counter <= 3'b100;
parity_xor <= ^tf_data_bak[4:0];
end
2'b01 : begin
bit_counter <= 3'b101;
parity_xor <= ^tf_data_bak[5:0];
end
2'b10 : begin
bit_counter <= 3'b110;
parity_xor <= ^tf_data_bak[6:0];
end
2'b11 : begin
bit_counter <= 3'b111;
parity_xor <= ^tf_data_bak[7:0];
end
endcase
{shift_out[6:0], bit_out} <= tf_data_bak;
end
else begin
tf_pop <= 1'b1;
error_time <= 3'h0;
case (lcr[1:0])
2'b00 : begin
bit_counter <= 3'b100;
parity_xor <= ^tf_data_out[4:0];
end
2'b01 : begin
bit_counter <= 3'b101;
parity_xor <= ^tf_data_out[5:0];
end
2'b10 : begin
bit_counter <= 3'b110;
parity_xor <= ^tf_data_out[6:0];
end
2'b11 : begin
bit_counter <= 3'b111;
parity_xor <= ^tf_data_out[7:0];
end
endcase
{shift_out[6:0], bit_out} <= tf_data_out;
tf_data_bak <= tf_data_out;
end
tstate <= s_send_start;
end
s_send_start : begin
tf_pop <= 1'b0;
if (~|counter)
counter <= 5'b01111;
else if (counter == 5'b00001)
begin
counter <= 0;
tstate <= s_send_byte;
end
else
counter <= counter - 1'b1;
stx_o_tmp <= 1'b0;
end
s_send_byte : begin
if (~|counter)
counter <= 5'b01111;
else if (counter == 5'b00001)
begin
if (bit_counter > 3'b0) begin
bit_counter <= bit_counter - 1'b1;
{shift_out[5:0],bit_out } <= {shift_out[6:1], shift_out[0]};
tstate <= s_send_byte;
end
else
if (~lcr[`UART_LC_PE]) begin
tstate <= s_send_stop;
end
else begin
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
2'b00: bit_out <= ~parity_xor;
2'b01: bit_out <= 1'b1;
2'b10: bit_out <= parity_xor;
2'b11: bit_out <= 1'b0;
endcase
tstate <= s_send_parity;
end
counter <= 0;
end
else counter <= counter - 1'b1;
stx_o_tmp <= bit_out;
end
s_send_parity : begin
if (~|counter) counter <= 5'b01111;
else if (counter == 5'b00001) begin
counter <= 4'b0;
tstate <= usart_mode ? s_send_guard1 : s_send_stop;
end
else counter <= counter - 1'b1;
stx_o_tmp <= bit_out;
end
s_send_stop : begin
if (~|counter) begin
if(usart_t0)
counter <= tx_error ? 5'b11101 : 5'b01101;
else
casex ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]})
3'b0xx: counter <= 5'b01101;
3'b100: counter <= 5'b10101;
default: counter <= 5'b11101;
endcase
end
else if (counter == 5'b00001) begin
counter <= 5'b0;
tx2rx_en<= 1'b0;
tstate <= s_idle;
end
else counter <= counter - 1'b1;
stx_o_tmp <= 1'b1;
end
s_send_guard1:begin
if (~|counter) begin
tx2rx_en <= 1'b1;
counter <= usart_t0 ? 5'b01111:5'b01101;
end
else if (counter == 5'b00001) begin
counter <= 5'b0;
tx_error <= !srx_pad_i;
error_time<= error_time + !srx_pad_i;
tx2rx_en <= usart_t0 ? 1'b1 : 1'b0;
tstate <= usart_t0 ? s_send_stop : s_idle;
end
else counter <= counter - 1'b1;
stx_o_tmp <= 1'b1;
end
default :
tstate <= s_idle;
endcase
end
else tf_pop <= 1'b0;
end
assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp;
assign current_finish = usart_mode ? ( (tstate==3'b0)&(tx_error & (error_time ==repeat_time+1'b1) |~tx_error) ) : 1'b1;
endmodule

206
rtl/ip/APB_UART/apb_mux2.v Normal file
View File

@@ -0,0 +1,206 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`define APB_DEV0 6'h00
`define APB_DEV1 6'h1e
module apb_mux2 (
clk,
rst_n,
apb_ack_cpu,
apb_rw_cpu,
apb_psel_cpu,
apb_enab_cpu,
apb_addr_cpu,
apb_datai_cpu,
apb_datao_cpu,
apb_high_24b_rd,
apb_high_24b_wr,
apb_word_trans_cpu,
apb_ready_dma,
apb_rw_dma,
apb_psel_dma,
apb_enab_dma,
apb_addr_dma,
apb_wdata_dma,
apb_rdata_dma,
apb_valid_dma,
apb_valid_cpu,
dma_grant,
apb0_req,
apb0_ack,
apb0_rw,
apb0_psel,
apb0_enab,
apb0_addr,
apb0_datai,
apb0_datao,
apb1_req,
apb1_ack,
apb1_rw,
apb1_psel,
apb1_enab,
apb1_addr,
apb1_datai,
apb1_datao
);
parameter ADDR_APB = 20,
DATA_APB = 8,
DATA_APB_32 = 32;
input clk,rst_n;
output apb_ready_dma;
input apb_rw_dma;
input apb_psel_dma;
input apb_enab_dma;
input [ADDR_APB-1:0] apb_addr_dma;
input [31:0] apb_wdata_dma;
output[31:0] apb_rdata_dma;
output dma_grant;
input apb_valid_dma;
input apb_valid_cpu;
output apb_ack_cpu;
input apb_rw_cpu;
input apb_psel_cpu;
input apb_enab_cpu;
input [ADDR_APB-1:0] apb_addr_cpu;
input [DATA_APB-1:0] apb_datai_cpu;
output[DATA_APB-1:0] apb_datao_cpu;
output [23:0] apb_high_24b_rd;
input [23:0] apb_high_24b_wr;
output apb_word_trans_cpu;
output apb0_req;
input apb0_ack;
output apb0_rw;
output apb0_psel;
output apb0_enab;
output[ADDR_APB-1:0] apb0_addr;
output[DATA_APB-1:0] apb0_datai;
input [DATA_APB-1:0] apb0_datao;
output apb1_req;
input apb1_ack;
output apb1_rw;
output apb1_psel;
output apb1_enab;
output[ADDR_APB-1:0] apb1_addr;
output[31:0] apb1_datai;
input [31:0] apb1_datao;
wire apb_ack;
wire apb_rw;
wire apb_psel;
wire apb_enab;
wire [ADDR_APB-1:0] apb_addr;
wire [DATA_APB-1:0] apb_datai;
wire [23:0]high_24b_wr;
wire [23:0]high_24b_rd;
wire [7:0]apb_datao ;
wire dma_grant;
arb_2_1 arb_2_1(.clk(clk), .rst_n(rst_n), .valid0(apb_valid_cpu), .valid1(apb_valid_dma), .dma_grant(dma_grant));
assign apb_addr = dma_grant ? apb_addr_dma:apb_addr_cpu;
assign apb_rw = dma_grant ? apb_rw_dma:apb_rw_cpu;
assign apb_psel = dma_grant ? apb_psel_dma:apb_psel_cpu;
assign apb_enab = dma_grant ? apb_enab_dma:apb_enab_cpu;
assign apb_datai = dma_grant ? apb_wdata_dma[7:0]:apb_datai_cpu;
assign high_24b_wr = dma_grant ? apb_wdata_dma[31:8]:apb_high_24b_wr;
assign high_24b_rd = apb1_req ? apb1_datao[31:8] : 24'h0;
assign apb_word_trans_cpu = dma_grant ? 1'h0: apb1_req;
assign apb_high_24b_rd = dma_grant ? 24'h0: high_24b_rd;
assign apb_datao_cpu = dma_grant ? 8'h0: apb_datao;
assign apb_rdata_dma = dma_grant ? {high_24b_rd,apb_datao }:32'h0;
assign apb_ack_cpu = ~dma_grant & apb_ack;
assign apb_ready_dma = dma_grant & apb_ack;
assign apb0_req = (apb_addr[ADDR_APB-1:14] ==`APB_DEV0);
//assign apb1_req = (apb_addr[ADDR_APB-1:14] ==`APB_DEV1);
assign apb1_req = !apb0_req;
assign apb0_psel = apb_psel && apb0_req ;
assign apb1_psel = apb_psel && apb1_req;
assign apb0_enab = apb_enab && apb0_req ;
assign apb1_enab = apb_enab && apb1_req;
assign apb_ack = apb0_req ? apb0_ack :
apb1_req ? apb1_ack :
1'b0;
assign apb_datao = apb0_req ? apb0_datao :
apb1_req ? apb1_datao[7:0] :
8'b0;
assign apb0_addr = apb_addr;
assign apb0_datai = apb_datai;
assign apb0_rw = apb_rw;
assign apb1_addr = apb_addr;
assign apb1_datai = {high_24b_wr,apb_datai};
assign apb1_rw = apb_rw;
endmodule
module arb_2_1( clk, rst_n, valid0, valid1, dma_grant);
input clk;
input rst_n;
input valid0;
input valid1;
output dma_grant;
reg dma_grant;
always @(posedge clk)
if(~rst_n)
dma_grant<= 1'b0;
else if(valid0&&~valid1)
dma_grant<= 1'b0;
else if(valid1&&~valid0)
dma_grant<= 1'b1;
else if(valid0&&valid1&&~dma_grant)
dma_grant<= 1'b0;
else if(valid0&&valid1&&dma_grant)
dma_grant<= 1'b1;
else dma_grant<= 1'b0;
endmodule

674
rtl/ip/APB_UART/axi2apb.v Normal file
View File

@@ -0,0 +1,674 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "config.h"
module axi2apb_bridge(
clk,
rst_n,
axi_s_awid,
axi_s_awaddr,
axi_s_awlen,
axi_s_awsize,
axi_s_awburst,
axi_s_awlock,
axi_s_awcache,
axi_s_awprot,
axi_s_awvalid,
axi_s_awready,
axi_s_wid,
axi_s_wdata,
axi_s_wstrb,
axi_s_wlast,
axi_s_wvalid,
axi_s_wready,
axi_s_bid,
axi_s_bresp,
axi_s_bvalid,
axi_s_bready,
axi_s_arid,
axi_s_araddr,
axi_s_arlen,
axi_s_arsize,
axi_s_arburst,
axi_s_arlock,
axi_s_arcache,
axi_s_arprot,
axi_s_arvalid,
axi_s_arready,
axi_s_rid,
axi_s_rdata,
axi_s_rresp,
axi_s_rlast,
axi_s_rvalid,
axi_s_rready,
apb_valid_cpu,
cpu_grant,
apb_word_trans,
apb_high_24b_rd,
apb_high_24b_wr,
apb_clk,
apb_reset_n,
reg_psel,
reg_enable,
reg_rw,
reg_addr,
reg_datai,
reg_ready_1,
reg_datao
);
parameter L_ADDR_APB = 20;
input clk;
input rst_n;
input [`LID :0] axi_s_awid;
input [`Lawaddr -1 :0] axi_s_awaddr;
input [`Lawlen -1 :0] axi_s_awlen;
input [`Lawsize -1 :0] axi_s_awsize;
input [`Lawburst -1 :0] axi_s_awburst;
input [`Lawlock -1 :0] axi_s_awlock;
input [`Lawcache -1 :0] axi_s_awcache;
input [`Lawprot -1 :0] axi_s_awprot;
input axi_s_awvalid;
output axi_s_awready;
input [`LID :0] axi_s_wid;
input [`Lwdata -1 :0] axi_s_wdata;
input [`Lwstrb -1 :0] axi_s_wstrb;
input axi_s_wlast;
input axi_s_wvalid;
output axi_s_wready;
output [`LID :0] axi_s_bid;
output [`Lbresp -1 :0] axi_s_bresp;
output axi_s_bvalid;
input axi_s_bready;
input [`LID :0] axi_s_arid;
input [`Laraddr -1 :0] axi_s_araddr;
input [`Larlen -1 :0] axi_s_arlen;
input [`Larsize -1 :0] axi_s_arsize;
input [`Larburst -1 :0] axi_s_arburst;
input [`Larlock -1 :0] axi_s_arlock;
input [`Larcache -1 :0] axi_s_arcache;
input [`Larprot -1 :0] axi_s_arprot;
input axi_s_arvalid;
output axi_s_arready;
output [`LID :0] axi_s_rid;
output [`Lrdata -1 :0] axi_s_rdata;
output [`Lrresp -1 :0] axi_s_rresp;
output axi_s_rlast;
output axi_s_rvalid;
input axi_s_rready;
input apb_word_trans;
input cpu_grant;
output apb_valid_cpu;
input [23:0] apb_high_24b_rd;
output [23:0] apb_high_24b_wr;
output apb_clk;
output apb_reset_n;
output reg_psel;
output reg_enable;
output reg_rw;
output[L_ADDR_APB-1:0] reg_addr;
output[7:0] reg_datai;
input [7:0] reg_datao;
input reg_ready_1;
wire csr_rw_send_axi_rsp_done;
wire reg_ready;
parameter CSR_RW_SM_IDLE = 4'b0001,
CSR_RW_SM_GET_AXI_ADDR = 4'b0010,
CSR_RW_SM_SEND_AXI_RSP = 4'b1000;
reg reg_psel;
reg reg_enable;
reg axi_s_sel_rd;
reg axi_s_sel_wr;
reg[3:0] csr_rw_sm;
reg[3:0] csr_rw_sm_nxt;
reg[L_ADDR_APB-1:0] axi_s_req_addr;
reg[`LID:0] axi_s_w_id;
reg[`LID:0] axi_s_r_id;
reg[23:0] apb_high_24b_wr;
assign apb_clk = clk;
assign apb_reset_n = rst_n;
assign reg_rw = axi_s_sel_wr;
assign reg_addr = axi_s_req_addr;
assign reg_ready = reg_enable & reg_ready_1;
assign apb_valid_cpu = axi_s_sel_wr | axi_s_sel_rd | axi_s_awvalid | axi_s_arvalid;
reg axi_s_rlast;
reg axi_s_rvalid;
reg axi_s_wready;
reg axi_s_awready;
reg axi_s_arready;
reg [3:0]axi_s_rstrb;
reg [3:0]apb_s_wstrb;
reg [31:0]reg_datai_32;
reg [31:0]reg_datao_32;
reg [2:0] rd_count;
reg [2:0] apb_rd_size;
reg [2:0] apb_wr_size;
reg [7:0] reg_datai;
reg axi_s_bvalid;
always@(posedge clk)
begin
if(!rst_n)
begin
reg_datai_32 <= 32'h0;
reg_datao_32 <= 32'h0;
axi_s_req_addr <= 20'h0;
apb_s_wstrb <= 4'b0;
axi_s_rstrb <= 4'b0;
axi_s_wready <= 1'b0;
reg_enable <= 1'b0;
reg_psel <= 1'b0;
rd_count <= 3'b0;
apb_rd_size <= 3'b0;
apb_wr_size <= 3'b0;
axi_s_rlast <= 1'b0;
axi_s_rvalid <= 1'b0;
reg_datai <= 8'b0;
axi_s_awready <= 1'b0;
axi_s_arready <= 1'b0;
axi_s_bvalid <= 1'b0;
axi_s_sel_wr <= 1'b0;
axi_s_sel_rd <= 1'b0;
axi_s_w_id <= 'h0;
axi_s_r_id <= 'h0;
apb_high_24b_wr <= 24'h0;
end
else begin
if(axi_s_awvalid & ~axi_s_bvalid & ~axi_s_sel_rd & (csr_rw_sm == CSR_RW_SM_IDLE) &cpu_grant) begin
axi_s_req_addr <= axi_s_awaddr[L_ADDR_APB-1:0];
axi_s_awready <= 1'b1;
axi_s_sel_wr <= 1'b1;
apb_wr_size <= axi_s_awsize;
end
else if(axi_s_sel_wr) begin
axi_s_awready <= 1'b0;
if(axi_s_wvalid && ~axi_s_wready) begin
`ifdef AXI128
axi_s_req_addr <= (axi_s_wstrb[15:0]==16'h0002)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h1):
(axi_s_wstrb[15:0]==16'h0004)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h2):
(axi_s_wstrb[15:0]==16'h0008)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h3):
(axi_s_wstrb[15:0]==16'h0010)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'h4):
(axi_s_wstrb[15:0]==16'h0020)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h5):
(axi_s_wstrb[15:0]==16'h0040)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h6):
(axi_s_wstrb[15:0]==16'h0080)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h7):
(axi_s_wstrb[15:0]==16'h0100)&&(axi_s_req_addr[ 3]==1'h0)? (axi_s_req_addr + 4'h8):
(axi_s_wstrb[15:0]==16'h0200)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h9):
(axi_s_wstrb[15:0]==16'h0400)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'ha):
(axi_s_wstrb[15:0]==16'h0800)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'hb):
(axi_s_wstrb[15:0]==16'h1000)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'hc):
(axi_s_wstrb[15:0]==16'h2000)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'hd):
(axi_s_wstrb[15:0]==16'h4000)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'he):
(axi_s_wstrb[15:0]==16'h8000)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'hf):
(axi_s_wstrb[15:0]==16'h0006)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h1):
(axi_s_wstrb[15:0]==16'h000c)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h2):
(axi_s_wstrb[15:0]==16'h0018)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h3):
(axi_s_wstrb[15:0]==16'h0030)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'h4):
(axi_s_wstrb[15:0]==16'h0060)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h5):
(axi_s_wstrb[15:0]==16'h00c0)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h6):
(axi_s_wstrb[15:0]==16'h0180)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h7):
(axi_s_wstrb[15:0]==16'h0300)&&(axi_s_req_addr[ 3]==1'h0)? (axi_s_req_addr + 4'h8):
(axi_s_wstrb[15:0]==16'h0600)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h9):
(axi_s_wstrb[15:0]==16'h0c00)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'ha):
(axi_s_wstrb[15:0]==16'h1800)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'hb):
(axi_s_wstrb[15:0]==16'h3000)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'hc):
(axi_s_wstrb[15:0]==16'h6000)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'hd):
(axi_s_wstrb[15:0]==16'hc000)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'he):
(axi_s_wstrb[15:0]==16'h001e)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h1):
(axi_s_wstrb[15:0]==16'h003c)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h2):
(axi_s_wstrb[15:0]==16'h0078)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h3):
(axi_s_wstrb[15:0]==16'h00f0)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'h4):
(axi_s_wstrb[15:0]==16'h01e0)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h5):
(axi_s_wstrb[15:0]==16'h03c0)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h6):
(axi_s_wstrb[15:0]==16'h0780)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h7):
(axi_s_wstrb[15:0]==16'h0f00)&&(axi_s_req_addr[ 3]==1'h0)? (axi_s_req_addr + 4'h8):
(axi_s_wstrb[15:0]==16'h1e00)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h9):
(axi_s_wstrb[15:0]==16'h3c00)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'ha):
(axi_s_wstrb[15:0]==16'h7800)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'hb):
(axi_s_wstrb[15:0]==16'hf000)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'hc):
(axi_s_wstrb[15:0]==16'h01fe)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h1):
(axi_s_wstrb[15:0]==16'h03fc)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h2):
(axi_s_wstrb[15:0]==16'h07f8)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h3):
(axi_s_wstrb[15:0]==16'h0ff0)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 4'h4):
(axi_s_wstrb[15:0]==16'h1fe0)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h5):
(axi_s_wstrb[15:0]==16'h3fc0)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h6):
(axi_s_wstrb[15:0]==16'h7f80)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 4'h7):
(axi_s_wstrb[15:0]==16'hff00)&&(axi_s_req_addr[ 3]==1'h0)? (axi_s_req_addr + 4'h8): axi_s_req_addr ;
`elsif AXI64
axi_s_req_addr <= (axi_s_wstrb[7:0]==8'h02)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h1):
(axi_s_wstrb[7:0]==8'h04)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h2):
(axi_s_wstrb[7:0]==8'h08)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h3):
(axi_s_wstrb[7:0]==8'h10)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 2'h4):
(axi_s_wstrb[7:0]==8'h20)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h5):
(axi_s_wstrb[7:0]==8'h40)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h6):
(axi_s_wstrb[7:0]==8'h80)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h7):
(axi_s_wstrb[7:0]==8'h06)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h1):
(axi_s_wstrb[7:0]==8'h0c)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h2):
(axi_s_wstrb[7:0]==8'h18)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h3):
(axi_s_wstrb[7:0]==8'h30)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 2'h4):
(axi_s_wstrb[7:0]==8'h60)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h5):
(axi_s_wstrb[7:0]==8'hc0)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h6):
(axi_s_wstrb[7:0]==8'h1e)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h1):
(axi_s_wstrb[7:0]==8'h3c)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h2):
(axi_s_wstrb[7:0]==8'h78)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h3):
(axi_s_wstrb[7:0]==8'hf0)&&(axi_s_req_addr[ 2]==1'h0)? (axi_s_req_addr + 2'h4): axi_s_req_addr ;
`else
axi_s_req_addr <= (axi_s_wstrb[3:0]==4'h2)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h1):
(axi_s_wstrb[3:0]==4'h4)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h2):
(axi_s_wstrb[3:0]==4'h8)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h3):
(axi_s_wstrb[3:0]==4'h6)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h1):
(axi_s_wstrb[3:0]==4'hc)&&(axi_s_req_addr[1:0]==2'h0)? (axi_s_req_addr + 2'h2): axi_s_req_addr ;
`endif
axi_s_wready <= 1'b1;
reg_psel <= 1'b0;
reg_enable <= 1'b0;
axi_s_w_id <= axi_s_wid;
`ifdef AXI128
case({axi_s_req_addr[3:0]})
4'b0000: begin apb_s_wstrb <= axi_s_wstrb[ 3: 0]; reg_datai_32 <=axi_s_wdata[ 31: 0]; end
4'b0001: begin apb_s_wstrb <= axi_s_wstrb[ 4: 1]; reg_datai_32 <=axi_s_wdata[ 39: 8]; end
4'b0010: begin apb_s_wstrb <= axi_s_wstrb[ 5: 2]; reg_datai_32 <=axi_s_wdata[ 47: 16]; end
4'b0011: begin apb_s_wstrb <= axi_s_wstrb[ 6: 3]; reg_datai_32 <=axi_s_wdata[ 55: 24]; end
4'b0100: begin apb_s_wstrb <= axi_s_wstrb[ 7: 4]; reg_datai_32 <=axi_s_wdata[ 63: 32]; end
4'b0101: begin apb_s_wstrb <= axi_s_wstrb[ 8: 5]; reg_datai_32 <=axi_s_wdata[ 71: 40]; end
4'b0110: begin apb_s_wstrb <= axi_s_wstrb[ 9: 6]; reg_datai_32 <=axi_s_wdata[ 79: 48]; end
4'b0111: begin apb_s_wstrb <= axi_s_wstrb[10: 7]; reg_datai_32 <=axi_s_wdata[ 87: 56]; end
4'b1000: begin apb_s_wstrb <= axi_s_wstrb[11: 8]; reg_datai_32 <=axi_s_wdata[ 95: 64]; end
4'b1001: begin apb_s_wstrb <= axi_s_wstrb[12: 9]; reg_datai_32 <=axi_s_wdata[103: 72]; end
4'b1010: begin apb_s_wstrb <= axi_s_wstrb[13:10]; reg_datai_32 <=axi_s_wdata[111: 80]; end
4'b1011: begin apb_s_wstrb <= axi_s_wstrb[14:11]; reg_datai_32 <=axi_s_wdata[119: 88]; end
4'b1100: begin apb_s_wstrb <= axi_s_wstrb[15:12]; reg_datai_32 <=axi_s_wdata[127: 96]; end
4'b1101: begin apb_s_wstrb <= {1'b0, axi_s_wstrb[15:13]}; reg_datai_32 <={ 8'b0, axi_s_wdata[127:104]}; end
4'b1110: begin apb_s_wstrb <= {2'b0, axi_s_wstrb[15:14]}; reg_datai_32 <={16'b0, axi_s_wdata[127:112]}; end
4'b1111: begin apb_s_wstrb <= {3'b0, axi_s_wstrb[ 15]}; reg_datai_32 <={24'b0, axi_s_wdata[127:120]}; end
default: begin apb_s_wstrb <= 4'b0; reg_datai_32 <=32'h0; end
endcase
`elsif AXI64
case({axi_s_req_addr[2:0]})
3'b000: begin apb_s_wstrb <= axi_s_wstrb[3:0]; reg_datai_32 <=axi_s_wdata[31: 0]; end
3'b001: begin apb_s_wstrb <= axi_s_wstrb[4:1]; reg_datai_32 <=axi_s_wdata[39: 8]; end
3'b010: begin apb_s_wstrb <= axi_s_wstrb[5:2]; reg_datai_32 <=axi_s_wdata[47:16]; end
3'b011: begin apb_s_wstrb <= axi_s_wstrb[6:3]; reg_datai_32 <=axi_s_wdata[55:24]; end
3'b100: begin apb_s_wstrb <= axi_s_wstrb[7:4]; reg_datai_32 <=axi_s_wdata[63:32]; end
3'b101: begin apb_s_wstrb <= {1'b0, axi_s_wstrb[7:5]}; reg_datai_32 <={8 'b0, axi_s_wdata[63:40]}; end
3'b110: begin apb_s_wstrb <= {2'b0, axi_s_wstrb[7:6]}; reg_datai_32 <={16'b0, axi_s_wdata[63:48]}; end
3'b111: begin apb_s_wstrb <= {3'b0, axi_s_wstrb[ 7]}; reg_datai_32 <={24'b0, axi_s_wdata[63:56]}; end
default: begin apb_s_wstrb <= 4'b0; reg_datai_32 <=32'h0; end
endcase
`else
case({axi_s_req_addr[1:0]})
2'b00: begin apb_s_wstrb <= axi_s_wstrb[3:0]; reg_datai_32 <=axi_s_wdata[31:0]; end
2'b01: begin apb_s_wstrb <= {1'b0,axi_s_wstrb[3:1]}; reg_datai_32 <={8'h0,axi_s_wdata[31:8]}; end
2'b10: begin apb_s_wstrb <= {2'b0,axi_s_wstrb[3:2]}; reg_datai_32 <={16'b0,axi_s_wdata[31:16]}; end
2'b11: begin apb_s_wstrb <= {3'b0,axi_s_wstrb[3]}; reg_datai_32 <={24'b0,axi_s_wdata[31:24]}; end
default: begin apb_s_wstrb <= 4'b0; reg_datai_32 <=32'h0; end
endcase
`endif
end
else if((~reg_psel) && (apb_s_wstrb!=4'h0) ) begin
reg_psel <= 1'b1;
reg_enable <= 1'b0;
reg_datai <= (apb_s_wstrb == 4'h1) ? reg_datai_32[7:0]:
(apb_s_wstrb == 4'h2) ? reg_datai_32[15:8]:
(apb_s_wstrb == 4'h6) ? reg_datai_32[15:8]:
(apb_s_wstrb == 4'h4) ? reg_datai_32[23:16]:
(apb_s_wstrb == 4'h8) ? reg_datai_32[31:24]: reg_datai_32[7:0];
apb_high_24b_wr <= reg_datai_32[31:8];
if(axi_s_bready) axi_s_bvalid <= 1'b0;
end
else if(apb_word_trans & apb_s_wstrb==4'hf ) begin
if(~reg_ready)begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
else begin
reg_psel <= 1'b0;
reg_enable <= 1'b0;
axi_s_sel_wr <= 1'b0;
axi_s_bvalid <= 1'b1;
apb_s_wstrb <= 4'b0;
end
reg_datai <= reg_datai_32[7:0];
apb_high_24b_wr <= reg_datai_32[31:8];
axi_s_wready <= 1'b0;
end
else if(apb_s_wstrb[0]) begin
if(~reg_ready)begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
reg_datai <= reg_datai_32[7:0];
end
else begin
if(apb_s_wstrb[3:1] ==3'b0)
begin
reg_psel <= 1'b0;
axi_s_sel_wr<= 1'b0;
axi_s_bvalid <= 1'b1;
end
else
reg_psel <= 1'b1;
reg_enable <= 1'b0;
apb_s_wstrb[0] <= 1'b0;
axi_s_req_addr <= axi_s_req_addr +1'b1;
reg_datai <= reg_datai_32[15:8];
end
axi_s_wready <= 1'b0;
end
else if (apb_s_wstrb[1]) begin
if(~reg_ready)begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
else begin
if(apb_s_wstrb[3:2] ==2'b0)
begin
reg_psel <= 1'b0;
axi_s_sel_wr <= 1'b0;
axi_s_bvalid <= 1'b1;
end
else
reg_psel <= 1'b1;
reg_enable <= 1'b0;
apb_s_wstrb[1] <= 1'b0;
axi_s_req_addr <= axi_s_req_addr +1'b1;
reg_datai <= reg_datai_32[23:16];
end
axi_s_wready <= 1'b0;
end
else if (apb_s_wstrb[2]) begin
if(~reg_ready)begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
else begin
if(apb_s_wstrb[3] ==1'b0)
begin
reg_psel <= 1'b0;
axi_s_sel_wr <= 1'b0;
axi_s_bvalid <= 1'b1;
end
else
reg_psel <= 1'b1;
reg_enable <= 1'b0;
apb_s_wstrb[2] <= 1'b0;
axi_s_req_addr <= axi_s_req_addr +1'b1;
reg_datai <= reg_datai_32[31:24];
end
axi_s_wready <= 1'b0;
end
else if (apb_s_wstrb[3]) begin
if(~reg_ready)begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
else begin
reg_psel <= 1'b0;
reg_enable <= 1'b0;
axi_s_sel_wr <= 1'b0;
axi_s_bvalid <= 1'b1;
apb_s_wstrb[3] <= 1'b0;
end
axi_s_wready <= 1'b0;
end
else begin
reg_psel <= 1'b0;
reg_enable <= 1'b0;
reg_datai <= 8'h0;
apb_s_wstrb <= 4'h0;
axi_s_wready <= 1'b0;
if(csr_rw_sm == CSR_RW_SM_IDLE) axi_s_sel_wr <= 1'b0;
end
end
else if(axi_s_arvalid & ~axi_s_arready & ~axi_s_bvalid & (csr_rw_sm == CSR_RW_SM_IDLE)&cpu_grant)
begin
reg_enable <= 1'b0;
reg_psel <= 1'b1;
axi_s_arready <= 1'b1;
axi_s_sel_rd <= 1'b1;
axi_s_r_id <= axi_s_arid;
apb_rd_size <= axi_s_arsize;
axi_s_req_addr <= axi_s_araddr[L_ADDR_APB-1:0];
axi_s_rstrb <= axi_s_araddr[3:0];
if(axi_s_arsize==3'b010)
rd_count<= 3'h4;
else if(axi_s_arsize==3'b01)
rd_count<= 3'h2;
else if(axi_s_arsize==3'b0)
rd_count<= 3'h1;
end
else if(axi_s_sel_rd)
begin
axi_s_arready <= 1'b0;
if(apb_word_trans)
begin
if(reg_ready)
begin
reg_psel <= rd_count==3'b10;
reg_enable <= 1'b0;
rd_count <= rd_count-3'b1;
axi_s_rlast <= apb_rd_size==3'h2|rd_count==2'b1;
axi_s_rvalid <= apb_rd_size==3'h2|rd_count==2'b1;
axi_s_sel_rd <= rd_count==3'b10;
reg_datao_32 <= {apb_high_24b_rd,reg_datao};
end
else begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
end
else if(rd_count==3'h4)
begin
if(reg_ready)
begin
reg_psel <= 1'b1;
reg_enable <= 1'b0;
rd_count <= rd_count-3'h1;
reg_datao_32[7:0] <= reg_datao;
axi_s_req_addr <= axi_s_req_addr +1'b1;
end
else begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
end
else if(rd_count==3'h3)
begin
if(reg_ready)
begin
reg_psel <= 1'b1;
reg_enable <= 1'b0;
rd_count <= rd_count-3'h1;
reg_datao_32[15:8] <= reg_datao;
axi_s_req_addr <= axi_s_req_addr +1'b1;
end
else begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
end
else if(rd_count==3'h2)
begin
if(reg_ready)
begin
reg_psel <= 1'b1;
reg_enable <= 1'b0;
rd_count <= rd_count-3'h1;
axi_s_req_addr <= axi_s_req_addr +1'b1;
if(apb_rd_size==3'h2 )
reg_datao_32[23:16] <= reg_datao;
else if(apb_rd_size==3'h1)
reg_datao_32[7:0] <= reg_datao;
end
else begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
end
else if(rd_count==3'h1)
begin
if(reg_ready)
begin
reg_psel <= 1'b0;
reg_enable <= 1'b0;
axi_s_rlast <= 1'b1;
axi_s_rvalid <= 1'b1;
axi_s_sel_rd <= 1'b0;
if(apb_rd_size==3'h2 )
reg_datao_32[31:24] <= reg_datao;
else if(apb_rd_size==3'h1)
reg_datao_32[15:8] <= reg_datao;
else if(apb_rd_size==3'h0)
reg_datao_32[7:0] <= reg_datao;
end
else begin
reg_psel <= 1'b1;
reg_enable <= 1'b1;
end
end// end if(rd_count)
else begin
axi_s_arready <= 1'b0;
axi_s_rlast <= 1'b1;
axi_s_rvalid <= 1'b1;
reg_psel <= 1'b0;
reg_enable <= 1'b0;
if(axi_s_rvalid && axi_s_rready)
begin
reg_datao_32 <= 32'h0;
axi_s_rlast <= 1'b0;
axi_s_rvalid <= 1'b0;
end
if(csr_rw_sm == CSR_RW_SM_IDLE) axi_s_sel_rd <= 1'b0;
if(axi_s_bready) axi_s_bvalid <= 1'b0;
end
end//end if(axi_s_sel_rd)
else begin
reg_psel <= 1'b0;
reg_enable <= 1'b0;
axi_s_sel_wr <= 1'b0;
axi_s_sel_rd <= 1'b0;
axi_s_wready <= 1'b0;
axi_s_arready <= 1'b0;
axi_s_req_addr <= 32'h0;
reg_datai_32 <= 32'h0;
if(axi_s_bready) axi_s_bvalid <= 1'b0;
if(axi_s_rvalid && axi_s_rready)
begin
reg_datao_32 <= 32'h0;
axi_s_rlast <= 1'b0;
axi_s_rvalid <= 1'b0;
end
end
end//end if(rst_n)
end//end always
assign csr_rw_send_axi_rsp_done = csr_rw_sm == CSR_RW_SM_SEND_AXI_RSP && axi_s_rlast && axi_s_rready || axi_s_bvalid && axi_s_bready;
assign axi_s_bid = axi_s_w_id;
assign axi_s_rid = axi_s_r_id;
assign axi_s_bresp = 2'b00;
assign axi_s_rresp = 2'b00;
`ifdef AXI128
assign axi_s_rdata= ( axi_s_rstrb == 4'h0) ? {96'b0, reg_datao_32 } :
( axi_s_rstrb == 4'h1) ? {88'b0, reg_datao_32, 8'b0 } :
( axi_s_rstrb == 4'h2) ? {80'b0, reg_datao_32, 16'b0 } :
( axi_s_rstrb == 4'h3) ? {72'b0, reg_datao_32, 24'b0 } :
( axi_s_rstrb == 4'h4) ? {64'b0, reg_datao_32, 32'b0 } :
( axi_s_rstrb == 4'h5) ? {56'b0, reg_datao_32, 40'b0 } :
( axi_s_rstrb == 4'h6) ? {48'b0, reg_datao_32, 48'b0 } :
( axi_s_rstrb == 4'h7) ? {40'b0, reg_datao_32, 56'b0 } :
( axi_s_rstrb == 4'h8) ? {32'b0, reg_datao_32, 64'b0 } :
( axi_s_rstrb == 4'h9) ? {24'b0, reg_datao_32, 72'b0 } :
( axi_s_rstrb == 4'ha) ? {16'b0, reg_datao_32, 80'b0 } :
( axi_s_rstrb == 4'hb) ? { 8'b0, reg_datao_32, 88'b0 } :
( axi_s_rstrb == 4'hc) ? {reg_datao_32, 96'b0 } :
( axi_s_rstrb == 4'hd) ? {reg_datao_32[23:0], 104'b0 } :
( axi_s_rstrb == 4'he) ? {reg_datao_32[15:0], 112'b0 } :
( axi_s_rstrb == 4'hf) ? {reg_datao_32[ 7:0], 120'b0 } : 128'h0;
`elsif AXI64
assign axi_s_rdata= ( axi_s_rstrb[2:0] == 3'h0) ? {32'b0, reg_datao_32 } :
( axi_s_rstrb[2:0] == 3'h1) ? {24'b0, reg_datao_32, 8'b0 } :
( axi_s_rstrb[2:0] == 3'h2) ? {16'b0, reg_datao_32, 16'b0 } :
( axi_s_rstrb[2:0] == 3'h3) ? { 8'b0, reg_datao_32, 24'b0 } :
( axi_s_rstrb[2:0] == 3'h4) ? {reg_datao_32, 32'b0 } :
( axi_s_rstrb[2:0] == 3'h5) ? {reg_datao_32[23:0], 40'b0 } :
( axi_s_rstrb[2:0] == 3'h6) ? {reg_datao_32[15:0], 48'b0 } :
( axi_s_rstrb[2:0] == 3'h7) ? {reg_datao_32[ 7:0], 56'b0 } : 64'h0;
`else
assign axi_s_rdata= ( axi_s_rstrb[1:0] == 2'h0) ? { reg_datao_32 } :
( axi_s_rstrb[1:0] == 2'h1) ? {reg_datao_32[23:0], 8'h0} :
( axi_s_rstrb[1:0] == 2'h2) ? {reg_datao_32[15:0],16'h0} :
( axi_s_rstrb[1:0] == 2'h3) ? {reg_datao_32[7:0], 24'h0} : 32'h0;
`endif
always@(csr_rw_sm or axi_s_awvalid or axi_s_arvalid or axi_s_sel_rd or axi_s_sel_wr or
axi_s_wready or csr_rw_send_axi_rsp_done or cpu_grant) begin
case(csr_rw_sm)
CSR_RW_SM_IDLE:
if((axi_s_awvalid || axi_s_arvalid)&&~(axi_s_sel_wr||axi_s_sel_rd)&cpu_grant)
csr_rw_sm_nxt = CSR_RW_SM_GET_AXI_ADDR;
else
csr_rw_sm_nxt = CSR_RW_SM_IDLE;
CSR_RW_SM_GET_AXI_ADDR:
if(axi_s_sel_wr)
csr_rw_sm_nxt = CSR_RW_SM_SEND_AXI_RSP;
else if(axi_s_sel_rd)
csr_rw_sm_nxt = CSR_RW_SM_SEND_AXI_RSP;
else
csr_rw_sm_nxt = CSR_RW_SM_GET_AXI_ADDR;
CSR_RW_SM_SEND_AXI_RSP:
if(csr_rw_send_axi_rsp_done)
csr_rw_sm_nxt = CSR_RW_SM_IDLE;
else
csr_rw_sm_nxt = CSR_RW_SM_SEND_AXI_RSP;
default:
csr_rw_sm_nxt = CSR_RW_SM_IDLE;
endcase
end
always@(posedge clk) begin
if(!rst_n)
csr_rw_sm <= CSR_RW_SM_IDLE;
else
csr_rw_sm <= csr_rw_sm_nxt;
end
endmodule

View File

@@ -0,0 +1,356 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`include "config.h"
module axi_uart_controller
(
clk,
rst_n,
axi_s_awid,
axi_s_awaddr,
axi_s_awlen,
axi_s_awsize,
axi_s_awburst,
axi_s_awlock,
axi_s_awcache,
axi_s_awprot,
axi_s_awvalid,
axi_s_awready,
axi_s_wid,
axi_s_wdata,
axi_s_wstrb,
axi_s_wlast,
axi_s_wvalid,
axi_s_wready,
axi_s_bid,
axi_s_bresp,
axi_s_bvalid,
axi_s_bready,
axi_s_arid,
axi_s_araddr,
axi_s_arlen,
axi_s_arsize,
axi_s_arburst,
axi_s_arlock,
axi_s_arcache,
axi_s_arprot,
axi_s_arvalid,
axi_s_arready,
axi_s_rid,
axi_s_rdata,
axi_s_rresp,
axi_s_rlast,
axi_s_rvalid,
axi_s_rready,
apb_rw_dma,
apb_psel_dma,
apb_enab_dma,
apb_addr_dma,
apb_valid_dma,
apb_wdata_dma,
apb_rdata_dma,
apb_ready_dma,
dma_grant,
dma_req_o,
dma_ack_i,
uart0_txd_i,
uart0_txd_o,
uart0_txd_oe,
uart0_rxd_i,
uart0_rxd_o,
uart0_rxd_oe,
uart0_rts_o,
uart0_dtr_o,
uart0_cts_i,
uart0_dsr_i,
uart0_dcd_i,
uart0_ri_i,
uart0_int
);
parameter ADDR_APB = 20,
DATA_APB = 8;
input clk;
input rst_n;
input [`LID :0] axi_s_awid;
input [`Lawaddr -1 :0] axi_s_awaddr;
input [`Lawlen -1 :0] axi_s_awlen;
input [`Lawsize -1 :0] axi_s_awsize;
input [`Lawburst -1 :0] axi_s_awburst;
input [`Lawlock -1 :0] axi_s_awlock;
input [`Lawcache -1 :0] axi_s_awcache;
input [`Lawprot -1 :0] axi_s_awprot;
input axi_s_awvalid;
output axi_s_awready;
input [`LID :0] axi_s_wid;
input [`Lwdata -1 :0] axi_s_wdata;
input [`Lwstrb -1 :0] axi_s_wstrb;
input axi_s_wlast;
input axi_s_wvalid;
output axi_s_wready;
output [`LID :0] axi_s_bid;
output [`Lbresp -1 :0] axi_s_bresp;
output axi_s_bvalid;
input axi_s_bready;
input [`LID :0] axi_s_arid;
input [`Laraddr -1 :0] axi_s_araddr;
input [`Larlen -1 :0] axi_s_arlen;
input [`Larsize -1 :0] axi_s_arsize;
input [`Larburst -1 :0] axi_s_arburst;
input [`Larlock -1 :0] axi_s_arlock;
input [`Larcache -1 :0] axi_s_arcache;
input [`Larprot -1 :0] axi_s_arprot;
input axi_s_arvalid;
output axi_s_arready;
output [`LID :0] axi_s_rid;
output [`Lrdata -1 :0] axi_s_rdata;
output [`Lrresp -1 :0] axi_s_rresp;
output axi_s_rlast;
output axi_s_rvalid;
input axi_s_rready;
output apb_ready_dma;
input apb_rw_dma;
input apb_psel_dma;
input apb_enab_dma;
input [ADDR_APB-1:0] apb_addr_dma;
input [31:0] apb_wdata_dma;
output[31:0] apb_rdata_dma;
input apb_valid_dma;
output dma_grant;
output dma_req_o;
input dma_ack_i;
input uart0_txd_i;
output uart0_txd_o;
output uart0_txd_oe;
input uart0_rxd_i;
output uart0_rxd_o;
output uart0_rxd_oe;
output uart0_rts_o;
output uart0_dtr_o;
input uart0_cts_i;
input uart0_dsr_i;
input uart0_dcd_i;
input uart0_ri_i;
output uart0_int;
assign dma_req_o = 1'b0;
assign nand_dma_ack_i = dma_ack_i;
wire apb_ready_cpu;
wire apb_rw_cpu;
wire apb_psel_cpu;
wire apb_enab_cpu;
wire [ADDR_APB-1 :0] apb_addr_cpu;
wire [DATA_APB-1:0] apb_datai_cpu;
wire [DATA_APB-1:0] apb_datao_cpu;
wire apb_clk_cpu;
wire apb_reset_n_cpu;
wire apb_word_trans_cpu;
wire apb_valid_cpu;
wire dma_grant;
wire [23:0] apb_high_24b_rd;
wire [23:0] apb_high_24b_wr;
wire apb_rw_dma;
wire apb_psel_dma;
wire apb_enab_dma;
wire [31:0] apb_wdata_dma;
wire [31:0] apb_rdata_dma;
wire apb_clk_dma;
wire apb_reset_n_dma;
wire apb_uart0_req;
wire apb_uart0_ack;
wire apb_uart0_rw;
wire apb_uart0_enab;
wire apb_uart0_psel;
wire [ADDR_APB -1:0] apb_uart0_addr;
wire [DATA_APB -1:0] apb_uart0_datai;
wire [DATA_APB -1:0] apb_uart0_datao;
wire apb_nand_req;
wire apb_nand_ack;
wire apb_nand_rw;
wire apb_nand_enab;
wire apb_nand_psel;
wire [ADDR_APB -1:0] apb_nand_addr;
wire [31:0] apb_nand_datai;
wire [31:0] apb_nand_datao;
axi2apb_bridge AA_axi2apb_bridge_cpu
(
.clk (clk ),
.rst_n (rst_n ),
.axi_s_awid (axi_s_awid ),
.axi_s_awaddr (axi_s_awaddr ),
.axi_s_awlen (axi_s_awlen ),
.axi_s_awsize (axi_s_awsize ),
.axi_s_awburst (axi_s_awburst ),
.axi_s_awlock (axi_s_awlock ),
.axi_s_awcache (axi_s_awcache ),
.axi_s_awprot (axi_s_awprot ),
.axi_s_awvalid (axi_s_awvalid ),
.axi_s_awready (axi_s_awready ),
.axi_s_wid (axi_s_wid ),
.axi_s_wdata (axi_s_wdata ),
.axi_s_wstrb (axi_s_wstrb ),
.axi_s_wlast (axi_s_wlast ),
.axi_s_wvalid (axi_s_wvalid ),
.axi_s_wready (axi_s_wready ),
.axi_s_bid (axi_s_bid ),
.axi_s_bresp (axi_s_bresp ),
.axi_s_bvalid (axi_s_bvalid ),
.axi_s_bready (axi_s_bready ),
.axi_s_arid (axi_s_arid ),
.axi_s_araddr (axi_s_araddr ),
.axi_s_arlen (axi_s_arlen ),
.axi_s_arsize (axi_s_arsize ),
.axi_s_arburst (axi_s_arburst ),
.axi_s_arlock (axi_s_arlock ),
.axi_s_arcache (axi_s_arcache ),
.axi_s_arprot (axi_s_arprot ),
.axi_s_arvalid (axi_s_arvalid ),
.axi_s_arready (axi_s_arready ),
.axi_s_rid (axi_s_rid ),
.axi_s_rdata (axi_s_rdata ),
.axi_s_rresp (axi_s_rresp ),
.axi_s_rlast (axi_s_rlast ),
.axi_s_rvalid (axi_s_rvalid ),
.axi_s_rready (axi_s_rready ),
.apb_word_trans (apb_word_trans_cpu ),
.apb_high_24b_rd (apb_high_24b_rd ),
.apb_high_24b_wr (apb_high_24b_wr ),
.apb_valid_cpu (apb_valid_cpu ),
.cpu_grant (~dma_grant ),
.apb_clk (apb_clk_cpu ),
.apb_reset_n (apb_reset_n_cpu ),
.reg_psel (apb_psel_cpu ),
.reg_enable (apb_enab_cpu ),
.reg_rw (apb_rw_cpu ),
.reg_addr (apb_addr_cpu ),
.reg_datai (apb_datai_cpu ),
.reg_datao (apb_datao_cpu ),
.reg_ready_1 (apb_ready_cpu )
);
apb_mux2 u_apb_mux2
(
.clk (clk ),
.rst_n (rst_n ),
.apb_ready_dma (apb_ready_dma ),
.apb_rw_dma (apb_rw_dma ),
.apb_addr_dma (apb_addr_dma ),
.apb_psel_dma (apb_psel_dma ),
.apb_enab_dma (apb_enab_dma ),
.apb_wdata_dma (apb_wdata_dma ),
.apb_rdata_dma (apb_rdata_dma ),
.apb_valid_dma (apb_valid_dma ),
.apb_valid_cpu (apb_valid_cpu ),
.dma_grant (dma_grant ),
.apb_ack_cpu (apb_ready_cpu ),
.apb_rw_cpu (apb_rw_cpu ),
.apb_addr_cpu (apb_addr_cpu ),
.apb_psel_cpu (apb_psel_cpu ),
.apb_enab_cpu (apb_enab_cpu ),
.apb_datai_cpu (apb_datai_cpu ),
.apb_datao_cpu (apb_datao_cpu ),
.apb_high_24b_rd (apb_high_24b_rd),
.apb_high_24b_wr (apb_high_24b_wr),
.apb_word_trans_cpu (apb_word_trans_cpu ),
.apb0_req (apb_uart0_req ),
.apb0_ack (apb_uart0_ack ),
.apb0_rw (apb_uart0_rw ),
.apb0_psel (apb_uart0_psel ),
.apb0_enab (apb_uart0_enab ),
.apb0_addr (apb_uart0_addr ),
.apb0_datai (apb_uart0_datai ),
.apb0_datao (apb_uart0_datao ),
.apb1_req ( ),
.apb1_ack (1'b1 ),
.apb1_rw ( ),
.apb1_enab ( ),
.apb1_psel ( ),
.apb1_addr ( ),
.apb1_datai ( ),
.apb1_datao (32'b0 )
);
//uart0
assign apb_uart0_ack = apb_uart0_enab;
UART_TOP uart0
(
.PCLK (clk ),
.clk_carrier (1'b0 ),
.PRST_ (rst_n ),
.PSEL (apb_uart0_psel ),
.PENABLE (apb_uart0_enab ),
.PADDR (apb_uart0_addr[7:0] ),
.PWRITE (apb_uart0_rw ),
.PWDATA (apb_uart0_datai ),
.URT_PRDATA (apb_uart0_datao ),
.INT (uart0_int ),
.TXD_o (uart0_txd_o ),
.TXD_i (uart0_txd_i ),
.TXD_oe (uart0_txd_oe ),
.RXD_o (uart0_rxd_o ),
.RXD_i (uart0_rxd_i ),
.RXD_oe (uart0_rxd_oe ),
.RTS (uart0_rts_o ),
.CTS (uart0_cts_i ),
.DSR (uart0_dsr_i ),
.DCD (uart0_dcd_i ),
.DTR (uart0_dtr_o ),
.RI (uart0_ri_i )
);
endmodule