Commit 460d2a4b authored by Roberto Hexsel's avatar Roberto Hexsel

UART now has an independent register for clearing individual IRQs

parent 4bb81b94
......@@ -96,8 +96,9 @@ _uart_buff: .space 16*4 # up to 16 registers to be saved here
.set UART_tx_irq,0x10
.equ UCTRL,0 # UART registers
.equ USTAT,0
.equ UDATA,4
.equ USTAT,4
.equ UINTER,8
.equ UDATA,12
.text
.set noreorder
......@@ -127,10 +128,13 @@ UARTinterr:
lui $a0, %hi(HW_uart_addr)# get device's address
ori $a0, $a0, %lo(HW_uart_addr)
lw $k1, USTAT($a0) # Read status, remove interrupt request
lw $k1, USTAT($a0) # Read status
sw $k1, 0*4($k0) # and save UART status to memory
andi $a1, $k1, UART_rx_irq # Is this reception?
li $a1, UART_rx_irq # remove interrupt request
sw $a1, UINTER($a0)
and $a1, $k1, $a1 # Is this reception?
beq $a1, $zero, UARTret # no, ignore it and return
nop
......
......@@ -371,7 +371,7 @@ entity simple_uart is
clk : in std_logic; -- processor clock
sel : in std_logic;
wr : in std_logic;
addr : in std_logic;
addr : in std_logic_vector(1 downto 0);
data_inp : in std_logic_vector;
data_out : out std_logic_vector;
txdat : out std_logic; -- serial transmission (output)
......@@ -386,7 +386,7 @@ architecture behavioral of simple_uart is
component uart_int is
port(clk, rst: in std_logic;
s_ctrl, s_stat, s_tx, s_rx: in std_logic; -- select 4 registers
s_ctrl, s_stat, s_tx, s_rx, s_int: in std_logic; -- select registers
d_inp: in std_logic_vector; -- 32 bit input
d_out: out std_logic_vector; -- 32 bit output
txdat: out std_logic; -- serial transmission (output)
......@@ -397,25 +397,28 @@ architecture behavioral of simple_uart is
bit_rt: out std_logic_vector); -- communication speed - for TB only
end component uart_int;
signal s_ctrl, s_stat, s_tx, s_rx: std_logic;
signal s_ctrl, s_stat, s_tx, s_rx, s_int: std_logic;
signal d_inp, d_out : reg32;
begin
U_UART: uart_int port map (clk, rst, s_ctrl,s_stat, s_tx,s_rx,
U_UART: uart_int port map (clk, rst, s_ctrl,s_stat, s_tx,s_rx, s_int,
d_inp,d_out, txdat,rxdat, rts,cts, irq, bit_rt);
-- a2 wr register (aligned to word addresses)
-- 0 0 control
-- 0 1 status
-- 1 0 transmission
-- 1 1 reception
s_ctrl <= '1' when sel = '0' and addr = '0' and wr = '0' else '0';
s_stat <= '1' when sel = '0' and addr = '0' and wr = '1' else '0';
s_tx <= '1' when sel = '0' and addr = '1' and wr = '0' else '0';
s_rx <= '1' when sel = '0' and addr = '1' and wr = '1' else '0';
-- a3a2 wr register (aligned to word addresses)
-- 00 0 control, R+W IO_UART_ADDR +0
-- 01 1 status, R-O IO_UART_ADDR +4
-- 10 0 interrupt conmtrol W-O IO_UART_ADDR +8
-- 11 0 transmission W IO_UART_ADDR +12
-- 11 1 reception R IO_UART_ADDR +12
data_out <= d_out ;
s_ctrl <= '1' when sel = '0' and addr = b"00" and wr = '0' else '0'; -- R+W
s_stat <= '1' when sel = '0' and addr = b"01" and wr = '1' else '0'; -- R-O
s_int <= '1' when sel = '0' and addr = b"10" and wr = '0' else '0'; -- W-O
s_tx <= '1' when sel = '0' and addr = b"11" and wr = '0' else '0'; -- W+R
s_rx <= '1' when sel = '0' and addr = b"11" and wr = '1' else '0';
data_out <= d_out;
d_inp <= data_inp;
......
......@@ -152,7 +152,7 @@ architecture TB of tb_cMIPS is
clk : in std_logic;
sel : in std_logic;
wr : in std_logic;
addr : in std_logic;
addr : in std_logic_vector;
data_inp : in std_logic_vector;
data_out : out std_logic_vector;
txdat : out std_logic;
......@@ -646,7 +646,8 @@ begin -- TB
lcd_data, lcd_rs, lcd_rw, lcd_en, lcd_blon);
U_simple_uart: simple_uart
port map (rst,clk, io_uart_sel, wr, d_addr(2), cpu_data, uart_d_out,
port map (rst,clk, io_uart_sel, wr, d_addr(3 downto 2),
cpu_data, uart_d_out,
uart_txd, uart_rxd, uart_rts, uart_cts, uart_irq, bit_rt);
-- uncoment next line for loop back, comment out previous line
-- uart_txd, uart_txd, uart_rts, uart_cts, uart_irq, bit_rt);
......
......@@ -26,7 +26,7 @@
-- 001: 1/8 CPU clock rate -- for VHDL/C debugging only
-- 010: 1/16 CPU clock rate -- for VHDL/C debugging only
-- 011: 1/32 CPU clock rate -- for VHDL/C debugging only
-- 100: 230.400 bits per second
-- 100: 1/64 CPU clock rate -- for VHDL/C debugging only
-- 101: 115.200 bits per second
-- 110: 19.200 bits per second
-- 111: 9.600 bits per second
......@@ -45,17 +45,23 @@
-- b6: transmit buffer is empty
-- b7: Clear to Send (CTS) is active
--
-- when CPU reads from RXdat register, bits 0,1,3 are cleared
-- when CPU reads from STATUS register, bit 4 is cleared
-- when CPU reads from RXdat register, bits 0 and 1 cleared
--
-- interrupt clear register, least significant byte only
-- b2..b0: ignored, not used
-- b3=1: clear interrupt bit on RX buffer full
-- b4=1: clear interrupt bit on TX buffer empty
-- b5,,b7: ignored, not used
--
-- RX and TX circuits are dobule-buffered
--
library ieee; use ieee.std_logic_1164.all;
use work.p_WIRES.all;
entity uart_int is
port(clk, rst: in std_logic;
s_ctrl, s_stat, s_tx, s_rx: in std_logic; -- select registers
s_ctrl, s_stat, s_tx, s_rx, s_int : in std_logic; -- select registers
d_inp: in reg32; -- input
d_out: out reg32; -- output
txdat: out std_logic; -- interface: serial transmission
......@@ -69,6 +75,13 @@ end uart_int;
architecture estrutural of uart_int is
constant CLOCK_DIVIDER : integer := 50;
-- bit in ctrl registers to set/clear the RTS serial interface signal
constant RTS_B : integer := 7;
-- bit in ctrl/interrupt registers to set/clear TX interrupt request
constant IRQ_TX_B : integer := 4;
-- bit in ctrl/interrupt registers to set/clear RX interrupt request
constant IRQ_RX_B : integer := 3;
component register8 is
port(clk, rst, ld: in std_logic;
......@@ -126,20 +139,22 @@ architecture estrutural of uart_int is
signal rx_ld, rx_shift, rx_next, rx_bfr_full : std_logic;
signal rxdat_1to0, rxdat_new, rxdat_int, rxdat_old : std_logic;
signal rxclk_fall, rxclk_rise, en_rx_clk, rx_done, rxclk : std_logic;
signal a_overrun, a_framing, reset_rxck, s_stat_dly : std_logic;
signal a_overrun, a_framing, reset_rxck : std_logic;
signal sta_xmit_sto, sta_recv_sto : reg10;
signal err_overrun, err_framing : std_logic;
signal rx_int_set, interr_RX_full, tx_int_set, interr_TX_empty : std_logic;
signal d_int_tx_empty, d_rx_int_set, d_err_framing, d_err_overrun : std_logic;
signal d_int_tx_empty,d_rx_int_set,d_err_framing,d_err_overrun : std_logic;
signal clear_tx_irq, clear_rx_irq : std_logic;
signal tx_baud_div, rx_baud_div : integer := 0;
begin
d_out <= x"000000" & received when s_rx = '1' else
x"000000" & status;
d_out <= x"000000" & received when s_rx = '1' else
x"000000" & status when s_stat = '1' else
x"000000" & ctrl;
rts <= ctrl(7);
rts <= ctrl(RTS_B);
-- for testing only: tells remote unit what is the transmission speed
bit_rt <= ctrl(2 downto 0);
......@@ -162,10 +177,12 @@ begin
U_transmit: par_ser10 port map (clk, rst, tx_ld, tx_next,
sta_xmit_sto, txdat);
U_STAT_DELAY: FFDsimple port map (clk, rst, s_stat, s_stat_dly);
-- U_STAT_DELAY: FFDsimple port map (clk, rst, s_tx, s_stat_dly);
clear_tx_irq <= '0' when s_int = '1' and d_inp(IRQ_TX_B) = '1' else '1';
tx_int_set <= ctrl(4) and tx_ld;
d_int_tx_empty <= (interr_TX_empty or tx_int_set) and not(s_stat_dly);
tx_int_set <= ctrl(IRQ_TX_B) and tx_ld;
d_int_tx_empty <= (interr_TX_empty or tx_int_set) and clear_tx_irq;
U_tx_int: FFDsimple port map (clk, rst, d_int_tx_empty, interr_TX_empty);
......@@ -367,9 +384,11 @@ begin
d_err_overrun <= (a_overrun or err_overrun) and not(s_rx);
U_overrun: FFDsimple port map (clk, rst, d_err_overrun, err_overrun);
clear_rx_irq <= '0' when s_int = '1' and d_inp(IRQ_RX_B) = '1' else '1';
rx_int_set <= ctrl(3) and rx_done;
d_rx_int_set <= (rx_int_set or interr_RX_full) and not(s_rx);
rx_int_set <= ctrl(IRQ_RX_B) and rx_done;
d_rx_int_set <= (rx_int_set or interr_RX_full) and clear_rx_irq;
U_rx_int: FFDsimple port map (clk, rst, d_rx_int_set, interr_RX_full);
......@@ -569,7 +588,7 @@ begin
8/2 when b"001",
16/2 when b"010",
32/2 when b"011",
217/2 when b"100", -- 230.400
64/2 when b"100",
434/2 when b"101", -- 115.200
2604/2 when b"110", -- 19.200
5208/2 when others; -- 9.600
......@@ -618,7 +637,7 @@ begin
8/2 when b"001",
16/2 when b"010",
32/2 when b"011",
217/2 when b"100", -- 230.400
64/2 when b"100",
434/2 when b"101", -- 115.200
2604/2 when b"110", -- 19.200
5208/2 when others; -- 9.600
......@@ -1060,7 +1079,7 @@ begin
8/2 when b"001",
16/2 when b"010",
32/2 when b"011",
217/2 when b"100", -- 230.400
64/2 when b"100",
434/2 when b"101", -- 115.200
2604/2 when b"110", -- 19.200
5208/2 when others; -- 9.600
......@@ -1088,7 +1107,7 @@ begin
8/2 when b"001",
16/2 when b"010",
32/2 when b"011",
217/2 when b"100", -- 230.400
64/2 when b"100",
434/2 when b"101", -- 115.200
2604/2 when b"110", -- 19.200
5208/2 when others; -- 9.600
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment