Commit c1277ee6 authored by Konstantinos Blantos's avatar Konstantinos Blantos

Working version of wb_uart used in ProFip

parent 9ef0c76a
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : simple_uart_pkg.vhd
-- Author : auto-generated by wbgen2 from simple_uart_wb.wb
-- Created : Fri Dec 8 11:12:47 2023
-- Created : Wed Dec 13 15:34:04 2023
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
......@@ -28,7 +28,7 @@ package uart_wbgen2_pkg is
sr_tx_fifo_empty_i : std_logic;
sr_tx_fifo_full_i : std_logic;
sr_rx_fifo_overflow_i : std_logic;
sr_rx_fifo_bytes_i : std_logic_vector(15 downto 0);
sr_rx_fifo_bytes_i : std_logic_vector(7 downto 0);
sr_physical_uart_i : std_logic;
sr_virtual_uart_i : std_logic;
rdr_rx_data_i : std_logic_vector(7 downto 0);
......@@ -36,6 +36,7 @@ package uart_wbgen2_pkg is
host_rdr_data_i : std_logic_vector(7 downto 0);
host_rdr_rdy_i : std_logic;
host_rdr_count_i : std_logic_vector(15 downto 0);
check_endianess_i : std_logic_vector(31 downto 0);
end record;
constant c_uart_in_registers_init_value: t_uart_in_registers := (
......@@ -54,7 +55,8 @@ package uart_wbgen2_pkg is
host_tdr_rdy_i => '0',
host_rdr_data_i => (others => '0'),
host_rdr_rdy_i => '0',
host_rdr_count_i => (others => '0')
host_rdr_count_i => (others => '0'),
check_endianess_i => (others => '0')
);
-- Output registers (WB slave -> user design)
......@@ -70,6 +72,8 @@ package uart_wbgen2_pkg is
host_tdr_data_wr_o : std_logic;
cr_rx_fifo_purge_o : std_logic;
cr_tx_fifo_purge_o : std_logic;
cr_tx_interrupt_enable_o : std_logic;
cr_rx_interrupt_enable_o : std_logic;
end record;
constant c_uart_out_registers_init_value: t_uart_out_registers := (
......@@ -82,14 +86,16 @@ package uart_wbgen2_pkg is
host_tdr_data_o => (others => '0'),
host_tdr_data_wr_o => '0',
cr_rx_fifo_purge_o => '0',
cr_tx_fifo_purge_o => '0'
cr_tx_fifo_purge_o => '0',
cr_tx_interrupt_enable_o => '0',
cr_rx_interrupt_enable_o => '0'
);
function "or" (left, right: t_uart_in_registers) return t_uart_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
function "or" (left, right: t_uart_in_registers) return t_uart_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component simple_uart_wb is
component simple_uart_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
......@@ -109,36 +115,36 @@ package uart_wbgen2_pkg is
regs_i : in t_uart_in_registers;
regs_o : out t_uart_out_registers
);
end component;
end component;
end package;
package body uart_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
begin
for i in 0 to x'length-1 loop
if(x(i) = '1') then
tmp(i):= '1';
else
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
end function;
function "or" (left, right: t_uart_in_registers) return t_uart_in_registers is
function "or" (left, right: t_uart_in_registers) return t_uart_in_registers is
variable tmp: t_uart_in_registers;
begin
begin
tmp.sr_tx_busy_i := f_x_to_zero(left.sr_tx_busy_i) or f_x_to_zero(right.sr_tx_busy_i);
tmp.sr_rx_rdy_i := f_x_to_zero(left.sr_rx_rdy_i) or f_x_to_zero(right.sr_rx_rdy_i);
tmp.sr_rx_fifo_supported_i := f_x_to_zero(left.sr_rx_fifo_supported_i) or f_x_to_zero(right.sr_rx_fifo_supported_i);
......@@ -155,7 +161,8 @@ package body uart_wbgen2_pkg is
tmp.host_rdr_data_i := f_x_to_zero(left.host_rdr_data_i) or f_x_to_zero(right.host_rdr_data_i);
tmp.host_rdr_rdy_i := f_x_to_zero(left.host_rdr_rdy_i) or f_x_to_zero(right.host_rdr_rdy_i);
tmp.host_rdr_count_i := f_x_to_zero(left.host_rdr_count_i) or f_x_to_zero(right.host_rdr_count_i);
tmp.check_endianess_i := f_x_to_zero(left.check_endianess_i) or f_x_to_zero(right.check_endianess_i);
return tmp;
end function;
end function;
end package body;
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : simple_uart_wb.vhd
-- Author : auto-generated by wbgen2 from simple_uart_wb.wb
-- Created : Fri Dec 8 11:12:47 2023
-- Created : Wed Dec 13 15:34:04 2023
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
......@@ -18,7 +18,7 @@ use work.uart_wbgen2_pkg.all;
entity simple_uart_wb is
port (
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
......@@ -36,7 +36,7 @@ entity simple_uart_wb is
host_rack_o : out std_logic;
regs_i : in t_uart_in_registers;
regs_o : out t_uart_out_registers
);
);
end simple_uart_wb;
architecture syn of simple_uart_wb is
......@@ -45,6 +45,8 @@ signal uart_cr_rx_fifo_purge_dly0 : std_logic ;
signal uart_cr_rx_fifo_purge_int : std_logic ;
signal uart_cr_tx_fifo_purge_dly0 : std_logic ;
signal uart_cr_tx_fifo_purge_int : std_logic ;
signal uart_cr_tx_interrupt_enable_int : std_logic ;
signal uart_cr_rx_interrupt_enable_int : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
......@@ -58,11 +60,11 @@ signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= wb_dat_i;
wrdata_reg <= wb_dat_i;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
......@@ -75,6 +77,8 @@ begin
host_rack_o <= '0';
uart_cr_rx_fifo_purge_int <= '0';
uart_cr_tx_fifo_purge_int <= '0';
uart_cr_tx_interrupt_enable_int <= '0';
uart_cr_rx_interrupt_enable_int <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
......@@ -111,9 +115,17 @@ begin
rddata_reg(5) <= regs_i.sr_tx_fifo_empty_i;
rddata_reg(6) <= regs_i.sr_tx_fifo_full_i;
rddata_reg(7) <= regs_i.sr_rx_fifo_overflow_i;
rddata_reg(23 downto 8) <= regs_i.sr_rx_fifo_bytes_i;
rddata_reg(24) <= regs_i.sr_physical_uart_i;
rddata_reg(25) <= regs_i.sr_virtual_uart_i;
rddata_reg(15 downto 8) <= regs_i.sr_rx_fifo_bytes_i;
rddata_reg(16) <= regs_i.sr_physical_uart_i;
rddata_reg(17) <= regs_i.sr_virtual_uart_i;
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
......@@ -287,13 +299,13 @@ begin
if (wb_we_i = '1') then
uart_cr_rx_fifo_purge_int <= wrdata_reg(0);
uart_cr_tx_fifo_purge_int <= wrdata_reg(1);
uart_cr_tx_interrupt_enable_int <= wrdata_reg(2);
uart_cr_rx_interrupt_enable_int <= wrdata_reg(3);
end if;
rddata_reg(0) <= '0';
rddata_reg(1) <= '0';
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(2) <= uart_cr_tx_interrupt_enable_int;
rddata_reg(3) <= uart_cr_rx_interrupt_enable_int;
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
......@@ -324,6 +336,12 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "111" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.check_endianess_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
......@@ -332,11 +350,11 @@ begin
end if;
end if;
end if;
end process;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
wb_dat_o <= rddata_reg;
-- TX busy
-- RX ready
-- RX FIFO supported
......@@ -345,27 +363,27 @@ begin
-- TX FIFO empty
-- TX FIFO full
-- RX FIFO overflow
regs_o.sr_rx_fifo_overflow_o <= wrdata_reg(7);
regs_o.sr_rx_fifo_overflow_o <= wrdata_reg(7);
-- RX FIFO data count
-- Physical UART
-- Virtual UART
-- Baudrate divider setting
-- pass-through field: Baudrate divider setting in register: Baudrate control register
regs_o.bcr_o <= wrdata_reg(31 downto 0);
regs_o.bcr_o <= wrdata_reg(31 downto 0);
-- Transmit data
-- pass-through field: Transmit data in register: Transmit data regsiter
regs_o.tdr_tx_data_o <= wrdata_reg(7 downto 0);
regs_o.tdr_tx_data_o <= wrdata_reg(7 downto 0);
-- Received data
-- TX Data
-- pass-through field: TX Data in register: Host VUART Tx register
regs_o.host_tdr_data_o <= wrdata_reg(7 downto 0);
regs_o.host_tdr_data_o <= wrdata_reg(7 downto 0);
-- TX Ready
-- RX Data
-- RX Ready
-- RX FIFO Count
-- RX FIFO purge
process (clk_sys_i, rst_n_i)
begin
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
uart_cr_rx_fifo_purge_dly0 <= '0';
regs_o.cr_rx_fifo_purge_o <= '0';
......@@ -373,12 +391,12 @@ begin
uart_cr_rx_fifo_purge_dly0 <= uart_cr_rx_fifo_purge_int;
regs_o.cr_rx_fifo_purge_o <= uart_cr_rx_fifo_purge_int and (not uart_cr_rx_fifo_purge_dly0);
end if;
end process;
end process;
-- TX FIFO purge
process (clk_sys_i, rst_n_i)
begin
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
uart_cr_tx_fifo_purge_dly0 <= '0';
regs_o.cr_tx_fifo_purge_o <= '0';
......@@ -386,13 +404,18 @@ begin
uart_cr_tx_fifo_purge_dly0 <= uart_cr_tx_fifo_purge_int;
regs_o.cr_tx_fifo_purge_o <= uart_cr_tx_fifo_purge_int and (not uart_cr_tx_fifo_purge_dly0);
end if;
end process;
end process;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- TX Interrupt enable
regs_o.cr_tx_interrupt_enable_o <= uart_cr_tx_interrupt_enable_int;
-- RX Interrupt enable
regs_o.cr_rx_interrupt_enable_o <= uart_cr_rx_interrupt_enable_int;
-- Check endianess register
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
wb_ack_o <= ack_sreg(0);
end syn;
......@@ -98,7 +98,7 @@ peripheral {
prefix = "RX_FIFO_BYTES";
type = SLV;
size = 16;
size = 8;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
......@@ -124,6 +124,7 @@ peripheral {
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
......@@ -240,7 +241,39 @@ peripheral {
prefix = "TX_FIFO_PURGE";
type = MONOSTABLE;
};
field {
name = "TX Interrupt enable";
description = "TX Interrupt Enable";
prefix = "TX_INTERRUPT_ENABLE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "RX Interrupt enable";
description = "RX Interrupt Enable";
prefix = "RX_INTERRUPT_ENABLE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Check Endianess";
description = "Register showing the endianess";
prefix = "CHECK_ENDIANESS";
field {
name = "Check endianess register";
description = "Register for endianess. Holds a default value based on which the user \
can check anytime the endianess. Default is big endianess";
type = SLV;
size = 32;
access_dev= WRITE_ONLY;
access_bus=READ_ONLY;
};
};
};
......@@ -33,7 +33,6 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
use work.genram_pkg.all;
use work.wishbone_pkg.all;
use work.UART_wbgen2_pkg.all;
......@@ -120,13 +119,12 @@ architecture arch of wb_simple_uart is
signal phys_rx_data, phys_tx_data : std_logic_vector(7 downto 0);
type t_tx_fifo_state is (IDLE, TRANSMIT_PENDING);
type t_rx_fifo_state is (IDLE, RX_READ, RX_WAIT_ACK );
signal tx_fifo_state : t_tx_fifo_state;
signal rx_fifo_state : t_rx_fifo_state;
signal rx_fifo_rdata : std_logic_vector(7 downto 0);
signal rx_fifo_wdata : std_logic_vector(7 downto 0);
signal s_rx_interrupt: std_logic;
signal s_tx_interrupt: std_logic;
begin -- arch
gen_check_generics : if (not g_WITH_PHYSICAL_UART and not g_WITH_VIRTUAL_UART) generate
......@@ -223,38 +221,34 @@ begin -- arch
baud8_tick_i => baud_tick8,
rxd_i => uart_rxd_i,
rx_ready_o => phys_rx_ready,
rx_error_o => open, -- fixme: support RX error detection
rx_error_o => open,
rx_data_o => phys_rx_data);
end generate gen_phys_uart;
gen_phys_fifos : if g_WITH_PHYSICAL_UART_FIFO generate
rx_fifo_wr <= not rx_fifo_full and (phys_rx_ready or ( f_to_std_logic(g_WITH_VIRTUAL_UART) and regs_out.host_tdr_data_wr_o ) );
rx_fifo_wr <= not rx_fifo_full and phys_rx_ready;
tx_fifo_wr <= not tx_fifo_full and regs_out.tdr_tx_data_wr_o;
tx_fifo_reset_n <= rst_n_i and not regs_out.cr_tx_fifo_purge_o;
rx_fifo_reset_n <= rst_n_i and not regs_out.cr_rx_fifo_purge_o;
-- RX FIFO write data: Physical UART takes the priority over VUART. Note these
-- are not meant to be used simultaneously.
rx_fifo_wdata <= phys_rx_data when phys_rx_ready = '1' else regs_out.host_tdr_data_o;
rx_fifo_rd <= not rx_fifo_empty and rdr_rack;
U_UART_RX_FIFO : generic_sync_fifo
generic map (
g_DATA_WIDTH => 8,
g_SIZE => g_RX_FIFO_SIZE,
g_WITH_COUNT => true,
g_SHOW_AHEAD => false
g_SHOW_AHEAD => true
)
port map (
rst_n_i => rx_fifo_reset_n,
clk_i => clk_sys_i,
d_i => rx_fifo_wdata,
d_i => phys_rx_data,
we_i => rx_fifo_wr,
q_o => rx_fifo_rdata,
rd_i => rx_fifo_rd,
q_o => regs_in.rdr_rx_data_i,
rd_i => rdr_rack,
empty_o => rx_fifo_empty,
full_o => rx_fifo_full,
count_o => rx_fifo_count);
......@@ -279,14 +273,12 @@ begin -- arch
regs_in.sr_rx_fifo_supported_i <= '1';
regs_in.sr_tx_fifo_supported_i <= '1';
regs_in.sr_rx_fifo_valid_i <= not rx_fifo_empty;
regs_in.sr_rx_rdy_i <= not rx_fifo_empty;
regs_in.sr_rx_fifo_overflow_i <= rx_fifo_overflow;
regs_in.sr_tx_fifo_full_i <= tx_fifo_full;
regs_in.sr_tx_fifo_empty_i <= tx_fifo_empty;
regs_in.sr_rx_fifo_bytes_i (rx_fifo_count'length-1 downto 0) <= rx_fifo_count;
regs_in.sr_rx_fifo_bytes_i ( 15 downto rx_fifo_count'length ) <= (others => '0');
phys_tx_start <= '1' when tx_fifo_state = IDLE and tx_fifo_empty = '0' else '0';
p_rx_fifo_overflow : process(clk_sys_i)
......@@ -295,11 +287,7 @@ begin -- arch
if rx_fifo_reset_n = '0' then
rx_fifo_overflow <= '0';
else
if regs_out.cr_rx_fifo_purge_o = '1' then
rx_fifo_overflow <= '0';
elsif rx_fifo_full = '1' then
rx_fifo_overflow <= '1';
end if;
end if;
end if;
end process;
......@@ -330,47 +318,14 @@ begin -- arch
end if;
end process;
regs_in.sr_tx_busy_i <= tx_fifo_full;
p_rx_fifo_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rx_fifo_reset_n = '0' then
rx_fifo_state <= IDLE;
regs_in.sr_rx_fifo_valid_i <= '0';
regs_in.sr_rx_rdy_i <= '0';
else
case rx_fifo_state is
when IDLE =>
regs_in.sr_rx_fifo_valid_i <= '0';
regs_in.sr_rx_rdy_i <= '0';
if rx_fifo_rd = '1' then
rx_fifo_state <= RX_READ;
end if;
when RX_READ =>
regs_in.rdr_rx_data_i <= rx_fifo_rdata;
regs_in.sr_rx_fifo_valid_i <= '1';
regs_in.sr_rx_rdy_i <= '1';
rx_fifo_state <= RX_WAIT_ACK;
when RX_WAIT_ACK =>
if( rdr_rack = '1' ) then
regs_in.sr_rx_fifo_valid_i <= '0';
regs_in.sr_rx_rdy_i <= '0';
rx_fifo_state <= IDLE;
end if;
end case;
end if;
end if;
end process;
-- Handling the interrupt for UART
s_rx_interrupt <= '1' when (rx_fifo_empty = '0' and regs_out.cr_rx_interrupt_enable_o = '1') else '0';
s_tx_interrupt <= '1' when (tx_fifo_full = '0' and regs_out.cr_tx_interrupt_enable_o = '1') else '0';
rx_fifo_rd <= '1' when rx_fifo_state = IDLE and rx_fifo_empty = '0' else '0';
int_o <= s_rx_interrupt or s_tx_interrupt;
regs_in.sr_tx_busy_i <= tx_fifo_full;
end generate gen_phys_fifos;
gen_phys_nofifos : if not g_WITH_PHYSICAL_UART_FIFO generate
......@@ -457,8 +412,12 @@ begin -- arch
regs_in.host_tdr_rdy_i <= not regs_in.sr_rx_rdy_i;
-- Registers to set if the Physical or Virtual UART is present
-- Registers used to clarify if we use Physical or Virtual UART
regs_in.sr_physical_uart_i <= '1' when g_WITH_PHYSICAL_UART else '0';
regs_in.sr_virtual_uart_i <= '1' when g_WITH_VIRTUAL_UART else '0';
-- Register to check the endianess. Holds a default value and when user reads
-- it as it is, it means the endianess is big, else it is little
regs_in.check_endianess_i <= x"AABBCCDD";
end arch;
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