Skip to content
Snippets Groups Projects
Commit 15bd8348 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Tomasz Wlostowski
Browse files

modules: wb_simple_uart: merged with wb_virtual_uart, added WB slave adapter

parent e8985b59
Branches
Tags
No related merge requests found
files = [ "uart_async_rx.vhd", files = [ "uart_async_rx.vhd",
"uart_async_tx.vhd", "uart_async_tx.vhd",
"uart_baud_gen.vhd", "uart_baud_gen.vhd",
"uart_wb_slave.vhd", "simple_uart_wb.vhd",
"wb_simple_uart.vhd"]; "simple_uart_pkg.vhd",
"wb_simple_uart.vhd",
"xwb_simple_uart.vhd"];
#!/bin/bash #!/bin/bash
mkdir -p doc mkdir -p doc
wbgen2 -D ./doc/wb_uart.html -V uart_wb_slave.vhd -C ../../../../software/include/hw/wb_uart.h --cstyle defines --lang vhdl -K ../../../sim/wb_uart_defs.v uart.wb wbgen2 -D ./doc/wb_simple_uart.html -V simple_uart_wb.vhd -p simple_uart_pkg.vhd --cstyle struct -C wb_uart.h --hstyle record --lang vhdl simple_uart_wb.wb
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Simple Wishbone UART
---------------------------------------------------------------------------------------
-- File : simple_uart_pkg.vhd
-- Author : auto-generated by wbgen2 from simple_uart_wb.wb
-- Created : Tue Oct 4 18:46:41 2011
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package uart_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_uart_in_registers is record
sr_tx_busy_i : std_logic;
sr_rx_rdy_i : std_logic;
rdr_rx_data_i : std_logic_vector(7 downto 0);
host_tdr_rdy_i : std_logic;
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);
end record;
constant c_uart_in_registers_init_value: t_uart_in_registers := (
sr_tx_busy_i => '0',
sr_rx_rdy_i => '0',
rdr_rx_data_i => (others => '0'),
host_tdr_rdy_i => '0',
host_rdr_data_i => (others => '0'),
host_rdr_rdy_i => '0',
host_rdr_count_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_uart_out_registers is record
bcr_o : std_logic_vector(31 downto 0);
bcr_wr_o : std_logic;
tdr_tx_data_o : std_logic_vector(7 downto 0);
tdr_tx_data_wr_o : std_logic;
host_tdr_data_o : std_logic_vector(7 downto 0);
host_tdr_data_wr_o : std_logic;
end record;
constant c_uart_out_registers_init_value: t_uart_out_registers := (
bcr_o => (others => '0'),
bcr_wr_o => '0',
tdr_tx_data_o => (others => '0'),
tdr_tx_data_wr_o => '0',
host_tdr_data_o => (others => '0'),
host_tdr_data_wr_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;
end package;
package body uart_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if(x = 'X' or x = 'U') then
return '0';
else
return x;
end if;
end function;
function "or" (left, right: t_uart_in_registers) return t_uart_in_registers is
variable tmp: t_uart_in_registers;
begin
tmp.sr_tx_busy_i := left.sr_tx_busy_i or right.sr_tx_busy_i;
tmp.sr_rx_rdy_i := left.sr_rx_rdy_i or right.sr_rx_rdy_i;
tmp.rdr_rx_data_i := left.rdr_rx_data_i or right.rdr_rx_data_i;
tmp.host_tdr_rdy_i := left.host_tdr_rdy_i or right.host_tdr_rdy_i;
tmp.host_rdr_data_i := left.host_rdr_data_i or right.host_rdr_data_i;
tmp.host_rdr_rdy_i := left.host_rdr_rdy_i or right.host_rdr_rdy_i;
tmp.host_rdr_count_i := left.host_rdr_count_i or right.host_rdr_count_i;
return tmp;
end function;
end package body;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Simple Wishbone UART
---------------------------------------------------------------------------------------
-- File : simple_uart_wb.vhd
-- Author : auto-generated by wbgen2 from simple_uart_wb.wb
-- Created : Tue Oct 4 18:46:41 2011
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.uart_wbgen2_pkg.all;
entity simple_uart_wb is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
rdr_rack_o : out std_logic;
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
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);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
regs_o.bcr_wr_o <= '0';
regs_o.tdr_tx_data_wr_o <= '0';
rdr_rack_o <= '0';
regs_o.host_tdr_data_wr_o <= '0';
host_rack_o <= '0';
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
regs_o.bcr_wr_o <= '0';
regs_o.tdr_tx_data_wr_o <= '0';
rdr_rack_o <= '0';
regs_o.host_tdr_data_wr_o <= '0';
host_rack_o <= '0';
ack_in_progress <= '0';
else
regs_o.bcr_wr_o <= '0';
regs_o.tdr_tx_data_wr_o <= '0';
regs_o.host_tdr_data_wr_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (wb_we_i = '1') then
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
else
rddata_reg(0) <= regs_i.sr_tx_busy_i;
rddata_reg(1) <= regs_i.sr_rx_rdy_i;
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
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';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "001" =>
if (wb_we_i = '1') then
regs_o.bcr_wr_o <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
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';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (wb_we_i = '1') then
regs_o.tdr_tx_data_wr_o <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
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';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "011" =>
if (wb_we_i = '1') then
else
rddata_reg(7 downto 0) <= regs_i.rdr_rx_data_i;
rdr_rack_o <= '1';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
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';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (wb_we_i = '1') then
regs_o.host_tdr_data_wr_o <= '1';
rddata_reg(8) <= 'X';
else
rddata_reg(8) <= regs_i.host_tdr_rdy_i;
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
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';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "101" =>
if (wb_we_i = '1') then
rddata_reg(8) <= 'X';
else
rddata_reg(7 downto 0) <= regs_i.host_rdr_data_i;
host_rack_o <= '1';
rddata_reg(8) <= regs_i.host_rdr_rdy_i;
rddata_reg(24 downto 9) <= regs_i.host_rdr_count_i;
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- TX busy
-- RX ready
-- Baudrate divider setting
-- pass-through field: Baudrate divider setting in register: Baudrate control register
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);
-- 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);
-- TX Ready
-- RX Data
-- RX Ready
-- RX FIFO Count
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
peripheral { peripheral {
name = "Simple Wishbone UART"; name = "Simple Wishbone UART";
description = "A simple Wishbone UART (8N1 mode) with programmable baud rate. "; description = "A simple Wishbone UART (8N1 mode) with programmable baud rate. ";
prefix = "UART"; prefix = "uart";
hdl_entity = "uart_wb_slave"; hdl_entity = "simple_uart_wb";
reg { reg {
name = "Status Register"; name = "Status Register";
...@@ -41,9 +41,7 @@ peripheral { ...@@ -41,9 +41,7 @@ peripheral {
description = "Baudrate setting. The value can be calculated using the following equation:\ description = "Baudrate setting. The value can be calculated using the following equation:\
BRATE = ((Baudrate * 8) << 9 + (ClockFreq >> 8)) / (ClockFreq >> 7)"; BRATE = ((Baudrate * 8) << 9 + (ClockFreq >> 8)) / (ClockFreq >> 7)";
size = 32; size = 32;
type = SLV; type = PASS_THROUGH;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
}; };
}; };
...@@ -55,18 +53,13 @@ peripheral { ...@@ -55,18 +53,13 @@ peripheral {
name = "Transmit data"; name = "Transmit data";
prefix = "TX_DATA"; prefix = "TX_DATA";
size = 8; size = 8;
type = SLV; type = PASS_THROUGH;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
}; };
}; };
reg { reg {
name = "Receive data regsiter"; name = "Receive data regsiter";
prefix = "RDR"; prefix = "RDR";
field { field {
ack_read = "rdr_rack_o"; ack_read = "rdr_rack_o";
name = "Received data"; name = "Received data";
...@@ -77,4 +70,56 @@ peripheral { ...@@ -77,4 +70,56 @@ peripheral {
access_dev = WRITE_ONLY; access_dev = WRITE_ONLY;
}; };
}; };
reg {
name = "Host VUART Tx register";
prefix = "HOST_TDR";
field {
name = "TX Data";
prefix = "DATA";
type = PASS_THROUGH;
size = 8;
};
field {
name = "TX Ready";
prefix = "RDY";
type= BIT;
access_dev= WRITE_ONLY;
access_bus=READ_ONLY;
};
};
reg {
name = "Host VUART Rx register";
prefix = "HOST_RDR";
field {
ack_read = "host_rack_o";
name = "RX Data";
prefix = "DATA";
type = SLV;
size = 8;
access_dev= WRITE_ONLY;
access_bus=READ_ONLY;
};
field {
name = "RX Ready";
prefix = "RDY";
type= BIT;
access_dev= WRITE_ONLY;
access_bus=READ_ONLY;
};
field {
name = "RX FIFO Count";
prefix = "COUNT";
type = SLV;
size = 16;
access_dev= WRITE_ONLY;
access_bus=READ_ONLY;
};
};
}; };
\ No newline at end of file
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Title : Wishbone UART for WR Core -- Title : Simple Wishbone UART
-- Project : WhiteRabbit -- Project : General Cores Collection (gencores) library
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- File : wb_conmax_top.vhd -- File : wb_simple_uart.vhd
-- Author : Tomasz Wlostowski -- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT -- Company : CERN BE-Co-HT
-- Created : 2011-02-21 -- Created : 2011-02-21
-- Last update: 2011-02-21 -- Last update: 2011-10-04
-- Platform : FPGA-generics -- Platform : FPGA-generics
-- Standard : VHDL -- Standard : VHDL'93
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Description: -- Description: A simple UART controller, providing two modes of operation
-- Simple UART port with Wishbone interface -- (both can be used simultenously):
-- -- - physical UART (encoding fixed to 8 data bits, no parity and one stop bit)
-- - virtual UART: TXed data is passed via a FIFO to the Wishbone host (and
-- vice versa).
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Copyright (c) 2011 Tomasz Wlostowski -- Copyright (c) 2011 CERN
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Revisions : -- Revisions :
-- Date Version Author Description -- Date Version Author Description
-- 2011-02-21 1.0 twlostow Created -- 2011-02-21 1.0 twlostow Created
-- 2011-10-04 1.1 twlostow merged with VUART, added adapter
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use work.genram_pkg.all;
use work.wishbone_pkg.all;
use work.UART_wbgen2_pkg.all;
entity wb_simple_uart is entity wb_simple_uart is
generic(
g_with_virtual_uart : boolean;
g_with_physical_uart : boolean;
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD
);
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0); wb_adr_i : in std_logic_vector(4 downto 0);
wb_data_i : in std_logic_vector(31 downto 0); wb_dat_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0); wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic; wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0); wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic; wb_stb_i : in std_logic;
wb_we_i : in std_logic; wb_we_i : in std_logic;
wb_ack_o : out std_logic; wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
uart_rxd_i : in std_logic; uart_rxd_i : in std_logic;
uart_txd_o : out std_logic uart_txd_o : out std_logic
...@@ -46,30 +60,8 @@ end wb_simple_uart; ...@@ -46,30 +60,8 @@ end wb_simple_uart;
architecture syn of wb_simple_uart is architecture syn of wb_simple_uart is
constant c_baud_acc_width : integer := 16; constant c_baud_acc_width : integer := 16;
constant c_vuart_fifo_size : integer := 1024;
component uart_wb_slave
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
uart_sr_tx_busy_i : in std_logic;
uart_sr_rx_rdy_i : in std_logic;
uart_bcr_o : out std_logic_vector(31 downto 0);
uart_tdr_tx_data_o : out std_logic_vector(7 downto 0);
uart_tdr_tx_data_i : in std_logic_vector(7 downto 0);
uart_tdr_tx_data_load_o : out std_logic;
uart_rdr_rx_data_i : in std_logic_vector(7 downto 0);
rdr_rack_o : out std_logic);
end component;
component uart_baud_gen component uart_baud_gen
generic ( generic (
...@@ -77,19 +69,18 @@ architecture syn of wb_simple_uart is ...@@ -77,19 +69,18 @@ architecture syn of wb_simple_uart is
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
baudrate_i : in std_logic_vector(g_baud_acc_width downto 0); baudrate_i : in std_logic_vector(g_baud_acc_width downto 0);
baud_tick_o : out std_logic; baud_tick_o : out std_logic;
baud8_tick_o : out std_logic); baud8_tick_o : out std_logic);
end component; end component;
component uart_async_rx component uart_async_rx
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
baud8_tick_i : in std_logic; baud8_tick_i : in std_logic;
rxd_i : in std_logic; rxd_i : in std_logic;
rx_ready_o : out std_logic; rx_ready_o : out std_logic;
rx_error_o : out std_logic; rx_error_o : out std_logic;
rx_data_o : out std_logic_vector(7 downto 0)); rx_data_o : out std_logic_vector(7 downto 0));
end component; end component;
...@@ -105,88 +96,204 @@ architecture syn of wb_simple_uart is ...@@ -105,88 +96,204 @@ architecture syn of wb_simple_uart is
tx_busy_o : out std_logic); tx_busy_o : out std_logic);
end component; end component;
component simple_uart_wb
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
rdr_rack_o : out std_logic;
host_rack_o : out std_logic;
regs_i : in t_uart_in_registers;
regs_o : out t_uart_out_registers);
end component;
signal rx_ready_reg : std_logic; signal rx_ready_reg : std_logic;
signal rx_ready : std_logic; signal rx_ready : std_logic;
signal uart_sr_tx_busy : std_logic;
signal uart_sr_rx_rdy : std_logic;
signal uart_bcr : std_logic_vector(31 downto 0); signal uart_bcr : std_logic_vector(31 downto 0);
signal uart_tdr_tx_data : std_logic_vector(7 downto 0);
signal uart_tdr_tx_data_load : std_logic;
signal uart_rdr_rx_data : std_logic_vector(7 downto 0);
signal rdr_rack : std_logic; signal rdr_rack : std_logic;
signal host_rack : std_logic;
signal baud_tick : std_logic; signal baud_tick : std_logic;
signal baud_tick8 : std_logic; signal baud_tick8 : std_logic;
signal resized_addr : std_logic_vector(c_wishbone_address_width-1 downto 0);
signal wb_in : t_wishbone_slave_in;
signal wb_out : t_wishbone_slave_out;
signal regs_in : t_UART_in_registers;
signal regs_out : t_UART_out_registers;
signal fifo_empty, fifo_full, fifo_rd, fifo_wr : std_logic;
signal fifo_count : std_logic_vector(f_log2_size(c_vuart_fifo_size)-1 downto 0);
signal phys_rx_ready, phys_tx_busy : std_logic;
signal phys_rx_data : std_logic_vector(7 downto 0);
begin -- syn begin -- syn
BAUD_GEN : uart_baud_gen gen_check_generics : if(not g_with_physical_uart and not g_with_virtual_uart) generate
assert false report "wb_simple_uart: dummy configuration (use virtual, physical or both uarts)" severity failure;
end generate gen_check_generics;
resized_addr(4 downto 0) <= wb_adr_i;
resized_addr(c_wishbone_address_width-1 downto 5) <= (others => '0');
U_Adapter : wb_slave_adapter
generic map ( generic map (
g_baud_acc_width => c_baud_acc_width) g_master_use_struct => true,
g_master_mode => CLASSIC,
g_master_granularity => WORD,
g_slave_use_struct => false,
g_slave_mode => g_interface_mode,
g_slave_granularity => g_address_granularity)
port map ( port map (
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
baudrate_i => uart_bcr(c_baud_acc_width downto 0), master_i => wb_out,
baud_tick_o => baud_tick, master_o => wb_in,
baud8_tick_o => baud_tick8); sl_adr_i => resized_addr,
sl_dat_i => wb_dat_i,
sl_sel_i => wb_sel_i,
sl_cyc_i => wb_cyc_i,
sl_stb_i => wb_stb_i,
sl_we_i => wb_we_i,
sl_dat_o => wb_dat_o,
sl_ack_o => wb_ack_o,
sl_stall_o => wb_stall_o);
TX : uart_async_tx U_WB_SLAVE : simple_uart_wb
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
baud_tick_i => baud_tick,
txd_o => uart_txd_o,
tx_start_p_i => uart_tdr_tx_data_load,
tx_data_i => uart_tdr_tx_data,
tx_busy_o => uart_sr_tx_busy);
RX : uart_async_rx
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
baud8_tick_i => baud_tick8,
rxd_i => uart_rxd_i,
rx_ready_o => rx_ready,
rx_error_o => open,
rx_data_o => uart_rdr_rx_data);
WB_SLAVE : uart_wb_slave
port map ( port map (
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
wb_clk_i => clk_sys_i, wb_clk_i => clk_sys_i,
wb_addr_i => wb_addr_i, wb_addr_i => wb_in.adr(2 downto 0),
wb_data_i => wb_data_i, wb_data_i => wb_in.dat,
wb_data_o => wb_data_o, wb_data_o => wb_out.dat,
wb_cyc_i => wb_cyc_i, wb_cyc_i => wb_in.cyc,
wb_sel_i => wb_sel_i, wb_sel_i => wb_in.sel,
wb_stb_i => wb_stb_i, wb_stb_i => wb_in.stb,
wb_we_i => wb_we_i, wb_we_i => wb_in.we,
wb_ack_o => wb_ack_o, wb_ack_o => wb_out.ack,
uart_sr_tx_busy_i => uart_sr_tx_busy, rdr_rack_o => rdr_rack,
uart_sr_rx_rdy_i => uart_sr_rx_rdy, host_rack_o => host_rack,
uart_bcr_o => uart_bcr, regs_o => regs_out,
uart_tdr_tx_data_o => uart_tdr_tx_data, regs_i => regs_in);
uart_tdr_tx_data_i => uart_tdr_tx_data,
uart_tdr_tx_data_load_o => uart_tdr_tx_data_load, gen_phys_uart : if(g_with_physical_uart) generate
uart_rdr_rx_data_i => uart_rdr_rx_data,
rdr_rack_o => rdr_rack); p_bcr_reg : process(clk_sys_i)
begin
process(clk_sys_i, rst_n_i) if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
uart_bcr <= (others => '0');
elsif(regs_out.bcr_wr_o = '1')then
uart_bcr <= regs_out.bcr_o;
end if;
end if;
end process;
U_BAUD_GEN : uart_baud_gen
generic map (
g_baud_acc_width => c_baud_acc_width)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
baudrate_i => uart_bcr(c_baud_acc_width downto 0),
baud_tick_o => baud_tick,
baud8_tick_o => baud_tick8);
U_TX : uart_async_tx
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
baud_tick_i => baud_tick,
txd_o => uart_txd_o,
tx_start_p_i => regs_out.tdr_tx_data_wr_o,
tx_data_i => regs_out.tdr_tx_data_o,
tx_busy_o => phys_tx_busy);
U_RX : uart_async_rx
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
baud8_tick_i => baud_tick8,
rxd_i => uart_rxd_i,
rx_ready_o => phys_rx_ready,
rx_error_o => open,
rx_data_o => phys_rx_data);
end generate gen_phys_uart;
gen_vuart : if(g_with_virtual_uart) generate
fifo_wr <= not fifo_full and regs_out.tdr_tx_data_wr_o;
fifo_rd <= not fifo_empty and not regs_in.host_rdr_rdy_i;
U_VUART_FIFO : generic_sync_fifo
generic map (
g_data_width => 8,
g_size => c_vuart_fifo_size,
g_with_count => true)
port map (
rst_n_i => rst_n_i,
clk_i => clk_sys_i,
d_i => regs_out.tdr_tx_data_o,
we_i => fifo_wr,
q_o => regs_in.host_rdr_data_i,
rd_i => fifo_rd,
empty_o => fifo_empty,
full_o => fifo_full,
count_o => fifo_count);
regs_in.host_rdr_count_i(fifo_count'left downto 0) <= fifo_count;
regs_in.host_rdr_count_i(15 downto fifo_count'length) <= (others => '0');
p_vuart_rx_ready : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
regs_in.host_rdr_rdy_i <= '0';
elsif(fifo_rd = '1') then
regs_in.host_rdr_rdy_i <= '1';
elsif(host_rack = '1') then
regs_in.host_rdr_rdy_i <= '0';
end if;
end if;
end process;
end generate gen_vuart;
p_drive_rx_ready : process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
uart_sr_rx_rdy <= '0'; regs_in.sr_rx_rdy_i <= '0';
regs_in.rdr_rx_data_i <= (others => '0');
else else
if(rx_ready = '1') then if(rdr_rack = '1' and phys_rx_ready = '0' and regs_out.host_tdr_data_wr_o = '0') then
uart_sr_rx_rdy <= '1'; regs_in.sr_rx_rdy_i <= '0';
elsif(rdr_rack = '1') then elsif(phys_rx_ready = '1' and g_with_physical_uart) then
uart_sr_rx_rdy <= '0'; regs_in.sr_rx_rdy_i <= '1';
regs_in.rdr_rx_data_i <= phys_rx_data;
elsif(regs_out.host_tdr_data_wr_o = '1' and g_with_virtual_uart) then
regs_in.sr_rx_rdy_i <= '1';
regs_in.rdr_rx_data_i <= regs_out.host_tdr_data_o;
end if; end if;
end if; end if;
end if; end if;
end process; end process;
regs_in.sr_tx_busy_i <= phys_tx_busy when (g_with_physical_uart) else '0';
end syn; end syn;
------------------------------------------------------------------------------
-- Title : Simple Wishbone UART
-- Project : General Cores Collection (gencores) library
------------------------------------------------------------------------------
-- File : xwb_simple_uart.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-05-18
-- Last update: 2011-10-04
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: A simple UART controller, providing two modes of operation
-- (both can be used simultenously):
-- - physical UART (encoding fixed to 8 data bits, no parity and one stop bit)
-- - virtual UART: TXed data is passed via a FIFO to the Wishbone host (and
-- vice versa).
-------------------------------------------------------------------------------
-- Copyright (c) 2010 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-05-18 1.0 twlostow Created
-- 2011-10-04 1.1 twlostow xwb module
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.wishbone_pkg.all;
entity xwb_simple_uart is
generic(
g_with_virtual_uart : boolean := true;
g_with_physical_uart : boolean := true;
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD
);
port(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
-- Wishbone
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
desc_o : out t_wishbone_device_descriptor;
uart_rxd_i: in std_logic;
uart_txd_o: out std_logic
);
end xwb_simple_uart;
architecture rtl of xwb_simple_uart is
component wb_simple_uart
generic (
g_with_virtual_uart : boolean;
g_with_physical_uart : boolean;
g_interface_mode : t_wishbone_interface_mode;
g_address_granularity : t_wishbone_address_granularity);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
wb_adr_i : in std_logic_vector(4 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
uart_rxd_i : in std_logic;
uart_txd_o : out std_logic);
end component;
begin -- rtl
U_Wrapped_UART: wb_simple_uart
generic map (
g_with_virtual_uart => g_with_virtual_uart,
g_with_physical_uart => g_with_physical_uart,
g_interface_mode => g_interface_mode,
g_address_granularity => g_address_granularity)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
wb_adr_i => slave_i.adr(4 downto 0),
wb_dat_i => slave_i.dat,
wb_dat_o => slave_o.dat,
wb_cyc_i => slave_i.cyc,
wb_sel_i => slave_i.sel,
wb_stb_i => slave_i.stb,
wb_we_i => slave_i.we,
wb_ack_o => slave_o.ack,
wb_stall_o => slave_o.stall,
uart_rxd_i => uart_rxd_i,
uart_txd_o => uart_txd_o);
end rtl;
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