From 15bd8348fa6a1a8624e1d8899c2caf602ba850cc Mon Sep 17 00:00:00 2001
From: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
Date: Wed, 5 Oct 2011 15:48:19 +0200
Subject: [PATCH] modules: wb_simple_uart: merged with wb_virtual_uart, added
 WB slave adapter

---
 modules/wishbone/wb_uart/Manifest.py          |   7 +
 modules/wishbone/wb_uart/build_wb.sh          |   2 +-
 modules/wishbone/wb_uart/manifest.py          |   5 -
 modules/wishbone/wb_uart/simple_uart_pkg.vhd  |  86 +++++
 modules/wishbone/wb_uart/simple_uart_wb.vhd   | 335 ++++++++++++++++++
 .../wb_uart/{uart.wb => simple_uart_wb.wb}    |  67 +++-
 modules/wishbone/wb_uart/wb_simple_uart.vhd   | 311 ++++++++++------
 modules/wishbone/wb_uart/xwb_simple_uart.vhd  | 104 ++++++
 8 files changed, 798 insertions(+), 119 deletions(-)
 create mode 100644 modules/wishbone/wb_uart/Manifest.py
 delete mode 100644 modules/wishbone/wb_uart/manifest.py
 create mode 100644 modules/wishbone/wb_uart/simple_uart_pkg.vhd
 create mode 100644 modules/wishbone/wb_uart/simple_uart_wb.vhd
 rename modules/wishbone/wb_uart/{uart.wb => simple_uart_wb.wb} (57%)
 create mode 100644 modules/wishbone/wb_uart/xwb_simple_uart.vhd

diff --git a/modules/wishbone/wb_uart/Manifest.py b/modules/wishbone/wb_uart/Manifest.py
new file mode 100644
index 00000000..fce05995
--- /dev/null
+++ b/modules/wishbone/wb_uart/Manifest.py
@@ -0,0 +1,7 @@
+files = [	"uart_async_rx.vhd",
+					"uart_async_tx.vhd",
+					"uart_baud_gen.vhd",
+					"simple_uart_wb.vhd",
+					"simple_uart_pkg.vhd",
+					"wb_simple_uart.vhd",
+					"xwb_simple_uart.vhd"];
diff --git a/modules/wishbone/wb_uart/build_wb.sh b/modules/wishbone/wb_uart/build_wb.sh
index 63156eac..6971eecc 100755
--- a/modules/wishbone/wb_uart/build_wb.sh
+++ b/modules/wishbone/wb_uart/build_wb.sh
@@ -1,4 +1,4 @@
 #!/bin/bash
 
 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 
diff --git a/modules/wishbone/wb_uart/manifest.py b/modules/wishbone/wb_uart/manifest.py
deleted file mode 100644
index 5568ec6a..00000000
--- a/modules/wishbone/wb_uart/manifest.py
+++ /dev/null
@@ -1,5 +0,0 @@
-files = [	"uart_async_rx.vhd",
-					"uart_async_tx.vhd",
-					"uart_baud_gen.vhd",
-					"uart_wb_slave.vhd",
-					"wb_simple_uart.vhd"];
diff --git a/modules/wishbone/wb_uart/simple_uart_pkg.vhd b/modules/wishbone/wb_uart/simple_uart_pkg.vhd
new file mode 100644
index 00000000..45b27351
--- /dev/null
+++ b/modules/wishbone/wb_uart/simple_uart_pkg.vhd
@@ -0,0 +1,86 @@
+---------------------------------------------------------------------------------------
+-- 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;
diff --git a/modules/wishbone/wb_uart/simple_uart_wb.vhd b/modules/wishbone/wb_uart/simple_uart_wb.vhd
new file mode 100644
index 00000000..058ba1ec
--- /dev/null
+++ b/modules/wishbone/wb_uart/simple_uart_wb.vhd
@@ -0,0 +1,335 @@
+---------------------------------------------------------------------------------------
+-- 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;
diff --git a/modules/wishbone/wb_uart/uart.wb b/modules/wishbone/wb_uart/simple_uart_wb.wb
similarity index 57%
rename from modules/wishbone/wb_uart/uart.wb
rename to modules/wishbone/wb_uart/simple_uart_wb.wb
index d211b76a..38ab2675 100644
--- a/modules/wishbone/wb_uart/uart.wb
+++ b/modules/wishbone/wb_uart/simple_uart_wb.wb
@@ -3,8 +3,8 @@
 peripheral {
 	 name = "Simple Wishbone UART";
 	 description = "A simple Wishbone UART (8N1 mode) with programmable baud rate. ";
-	 prefix = "UART";
-	 hdl_entity = "uart_wb_slave";
+	 prefix = "uart";
+	 hdl_entity = "simple_uart_wb";
 
 	 reg {
 			name = "Status Register";
@@ -41,9 +41,7 @@ peripheral {
 				 description = "Baudrate setting. The value can be calculated using the following equation:\
 				 BRATE = ((Baudrate * 8) << 9 + (ClockFreq >> 8)) / (ClockFreq >> 7)";
 				 size = 32;
-				 type = SLV;
-				 access_bus = READ_WRITE;
-				 access_dev = READ_ONLY;
+				 type = PASS_THROUGH;
 			};
 	 };
 
@@ -55,18 +53,13 @@ peripheral {
 				 name = "Transmit data";
 				 prefix = "TX_DATA";
 				 size = 8;
-				 type = SLV;
-				 access_bus = READ_WRITE;
-				 access_dev = READ_WRITE;
-				 load = LOAD_EXT;
+				 type = PASS_THROUGH;
 			};
 	 };
 	 
 	 reg {
 			name = "Receive data regsiter";
 			prefix = "RDR";
-			
-
 			field {
 				 ack_read = "rdr_rack_o";
 				 name = "Received data";
@@ -77,4 +70,56 @@ peripheral {
 				 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
diff --git a/modules/wishbone/wb_uart/wb_simple_uart.vhd b/modules/wishbone/wb_uart/wb_simple_uart.vhd
index 437a4f15..cba8b5f9 100644
--- a/modules/wishbone/wb_uart/wb_simple_uart.vhd
+++ b/modules/wishbone/wb_uart/wb_simple_uart.vhd
@@ -1,43 +1,57 @@
 -------------------------------------------------------------------------------
--- Title      : Wishbone UART for WR Core
--- Project    : WhiteRabbit
+-- Title      : Simple Wishbone UART
+-- Project    : General Cores Collection (gencores) library
 -------------------------------------------------------------------------------
--- File       : wb_conmax_top.vhd
+-- File       : wb_simple_uart.vhd
 -- Author     : Tomasz Wlostowski
 -- Company    : CERN BE-Co-HT
 -- Created    : 2011-02-21
--- Last update: 2011-02-21
+-- Last update: 2011-10-04
 -- Platform   : FPGA-generics
--- Standard   : VHDL
+-- Standard   : VHDL'93
 -------------------------------------------------------------------------------
--- Description:
--- Simple UART port with Wishbone interface
---
+-- 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) 2011 Tomasz Wlostowski
+-- Copyright (c) 2011 CERN
 -------------------------------------------------------------------------------
 -- Revisions  :
 -- Date        Version  Author          Description
 -- 2011-02-21  1.0      twlostow        Created
+-- 2011-10-04  1.1      twlostow        merged with VUART, added adapter
 -------------------------------------------------------------------------------
 
 library ieee;
 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
+  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 (
 
     clk_sys_i : in std_logic;
     rst_n_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;
+    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
@@ -46,30 +60,8 @@ end wb_simple_uart;
 
 architecture syn of wb_simple_uart is
 
-  constant c_baud_acc_width : integer := 16;
-
-  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;
+  constant c_baud_acc_width  : integer := 16;
+  constant c_vuart_fifo_size : integer := 1024;
 
   component uart_baud_gen
     generic (
@@ -77,19 +69,18 @@ architecture syn of wb_simple_uart is
     port (
       clk_sys_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;
       baud8_tick_o : out std_logic);
   end component;
 
-
   component uart_async_rx
     port (
       clk_sys_i    : in  std_logic;
       rst_n_i      : in  std_logic;
       baud8_tick_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_data_o    : out std_logic_vector(7 downto 0));
   end component;
@@ -105,88 +96,204 @@ architecture syn of wb_simple_uart is
       tx_busy_o    : out std_logic);
   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        : 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_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 host_rack : std_logic;
 
   signal baud_tick  : 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
 
-  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 (
-      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 (
-      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);
+      clk_sys_i  => clk_sys_i,
+      rst_n_i    => rst_n_i,
+      master_i   => wb_out,
+      master_o   => wb_in,
+      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
-    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
+  U_WB_SLAVE : simple_uart_wb
     port map (
       rst_n_i   => rst_n_i,
       wb_clk_i  => clk_sys_i,
-      wb_addr_i => wb_addr_i,
-      wb_data_i => wb_data_i,
-      wb_data_o => wb_data_o,
-      wb_cyc_i  => wb_cyc_i,
-      wb_sel_i  => wb_sel_i,
-      wb_stb_i  => wb_stb_i,
-      wb_we_i   => wb_we_i,
-      wb_ack_o  => wb_ack_o,
-
-      uart_sr_tx_busy_i       => uart_sr_tx_busy,
-      uart_sr_rx_rdy_i        => uart_sr_rx_rdy,
-      uart_bcr_o              => uart_bcr,
-      uart_tdr_tx_data_o      => uart_tdr_tx_data,
-      uart_tdr_tx_data_i      => uart_tdr_tx_data,
-      uart_tdr_tx_data_load_o => uart_tdr_tx_data_load,
-      uart_rdr_rx_data_i      => uart_rdr_rx_data,
-      rdr_rack_o              => rdr_rack);
-
-  process(clk_sys_i, rst_n_i)
+      wb_addr_i => wb_in.adr(2 downto 0),
+      wb_data_i => wb_in.dat,
+      wb_data_o => wb_out.dat,
+      wb_cyc_i  => wb_in.cyc,
+      wb_sel_i  => wb_in.sel,
+      wb_stb_i  => wb_in.stb,
+      wb_we_i   => wb_in.we,
+      wb_ack_o  => wb_out.ack,
+
+      rdr_rack_o  => rdr_rack,
+      host_rack_o => host_rack,
+      regs_o      => regs_out,
+      regs_i      => regs_in);
+
+  gen_phys_uart : if(g_with_physical_uart) generate
+
+    p_bcr_reg : process(clk_sys_i)
+    begin
+      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
     if rising_edge(clk_sys_i) 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
-        if(rx_ready = '1') then
-          uart_sr_rx_rdy <= '1';
-        elsif(rdr_rack = '1') then
-          uart_sr_rx_rdy <= '0';
+        if(rdr_rack = '1' and phys_rx_ready = '0' and regs_out.host_tdr_data_wr_o = '0') then
+          regs_in.sr_rx_rdy_i <= '0';
+        elsif(phys_rx_ready = '1' and g_with_physical_uart) then
+          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 process;
+
+  regs_in.sr_tx_busy_i <= phys_tx_busy when (g_with_physical_uart) else '0';
   
 end syn;
diff --git a/modules/wishbone/wb_uart/xwb_simple_uart.vhd b/modules/wishbone/wb_uart/xwb_simple_uart.vhd
new file mode 100644
index 00000000..0c4da820
--- /dev/null
+++ b/modules/wishbone/wb_uart/xwb_simple_uart.vhd
@@ -0,0 +1,104 @@
+------------------------------------------------------------------------------
+-- 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;
-- 
GitLab