From b60dd2563b531dfc9663fe8b8fb4300c0bec4ebb Mon Sep 17 00:00:00 2001
From: Dimitris Lampridis <dimitris.lampridis@cern.ch>
Date: Mon, 19 Nov 2018 09:54:18 +0100
Subject: [PATCH] wb_reg_link: add generics for instantiating wb adapters,
 since wb_reg_link works correctly only when used with pipelined wb interfaces

---
 .../wb_reg_link/xwb_register_link.vhd         | 90 ++++++++++++++-----
 modules/wishbone/wishbone_pkg.vhd             |  9 +-
 2 files changed, 74 insertions(+), 25 deletions(-)

diff --git a/modules/wishbone/wb_reg_link/xwb_register_link.vhd b/modules/wishbone/wb_reg_link/xwb_register_link.vhd
index f75ef92c..c5e61dfb 100644
--- a/modules/wishbone/wb_reg_link/xwb_register_link.vhd
+++ b/modules/wishbone/wb_reg_link/xwb_register_link.vhd
@@ -6,7 +6,7 @@
 -- Author     : Wesley W. Terpstra
 -- Company    : GSI
 -- Created    : 2013-12-16
--- Last update: 2018-11-08
+-- Last update: 2018-11-16
 -- Platform   : FPGA-generic
 -- Standard   : VHDL'93
 -------------------------------------------------------------------------------
@@ -32,7 +32,12 @@ use ieee.numeric_std.all;
 use work.wishbone_pkg.all;
 
 entity xwb_register_link is
-  port(
+  generic (
+    g_WB_IN_MODE         : t_wishbone_interface_mode      := PIPELINED;
+    g_WB_IN_GRANULARITY  : t_wishbone_address_granularity := BYTE;
+    g_WB_OUT_MODE        : t_wishbone_interface_mode      := PIPELINED;
+    g_WB_OUT_GRANULARITY : t_wishbone_address_granularity := BYTE);
+  port (
     clk_sys_i : in  std_logic;
     rst_n_i   : in  std_logic;
     slave_i   : in  t_wishbone_slave_in;
@@ -49,8 +54,47 @@ architecture rtl of xwb_register_link is
   signal r_cyc           : std_logic;
   signal r_dat           : t_wishbone_data;
 
+  signal slave_in   : t_wishbone_slave_in;
+  signal slave_out  : t_wishbone_slave_out;
+  signal master_in  : t_wishbone_master_in;
+  signal master_out : t_wishbone_master_out;
+
 begin
 
+  -- xwb_register_link only works with PIPELINED interfaces.
+  -- We convert from/to PIPELINED to enforce this.
+  wb_slave_adapter_in: wb_slave_adapter
+    generic map (
+      g_master_use_struct  => TRUE,
+      g_slave_use_struct   => TRUE,
+      g_slave_mode         => g_WB_IN_MODE,
+      g_slave_granularity  => g_WB_IN_GRANULARITY,
+      g_master_mode        => PIPELINED,
+      g_master_granularity => BYTE)
+    port map (
+      clk_sys_i  => clk_sys_i,
+      rst_n_i    => rst_n_i,
+      slave_i    => slave_i,
+      slave_o    => slave_o,
+      master_i   => slave_out,
+      master_o   => slave_in);
+
+  wb_slave_adapter_out: wb_slave_adapter
+    generic map (
+      g_master_use_struct  => TRUE,
+      g_slave_use_struct   => TRUE,
+      g_slave_mode         => PIPELINED,
+      g_slave_granularity  => BYTE,
+      g_master_mode        => g_WB_OUT_MODE,
+      g_master_granularity => g_WB_OUT_GRANULARITY)
+    port map (
+      clk_sys_i  => clk_sys_i,
+      rst_n_i    => rst_n_i,
+      slave_i    => master_out,
+      slave_o    => master_in,
+      master_i   => master_i,
+      master_o   => master_o);
+
   sp : wb_skidpad
   generic map(
     g_adrbits   => c_wishbone_address_width
@@ -62,27 +106,27 @@ begin
     pop_i        => s_pop,
     full_o       => s_full,
     empty_o      => s_empty,
-    adr_i        => slave_i.adr,
-    dat_i        => slave_i.dat,
-    sel_i        => slave_i.sel,
-    we_i         => slave_i.we,
-    adr_o        => master_o.adr,
-    dat_o        => master_o.dat,
-    sel_o        => master_o.sel,
-    we_o         => master_o.we
+    adr_i        => slave_in.adr,
+    dat_i        => slave_in.dat,
+    sel_i        => slave_in.sel,
+    we_i         => slave_in.we,
+    adr_o        => master_out.adr,
+    dat_o        => master_out.dat,
+    sel_o        => master_out.sel,
+    we_o         => master_out.we
   );
 
 
-  slave_o.ack   <= r_ack;
-  slave_o.err   <= r_err;
-  slave_o.dat   <= r_dat;
-  slave_o.rty   <= '0';
+  slave_out.ack   <= r_ack;
+  slave_out.err   <= r_err;
+  slave_out.dat   <= r_dat;
+  slave_out.rty   <= '0';
 
-  s_pop         <= not master_i.stall;
-  s_push        <= slave_i.cyc and slave_i.stb and not s_full;
-  slave_o.stall <= s_full;
-  master_o.stb  <= not s_empty;
-  master_o.cyc  <= r_cyc;
+  s_pop           <= not master_in.stall;
+  s_push          <= slave_in.cyc and slave_in.stb and not s_full;
+  slave_out.stall <= s_full;
+  master_out.stb  <= not s_empty;
+  master_out.cyc  <= r_cyc;
 
   main : process(clk_sys_i, rst_n_i) is
   begin
@@ -92,11 +136,11 @@ begin
       r_err  <= '0';
       r_dat  <= (others => '0');
     elsif rising_edge(clk_sys_i) then
-      r_cyc <= slave_i.cyc;
+      r_cyc <= slave_in.cyc;
       -- no flow control on ack/err
-      r_ack <= master_i.ack;
-      r_err <= master_i.err;
-      r_dat <= master_i.dat;
+      r_ack <= master_in.ack;
+      r_err <= master_in.err;
+      r_dat <= master_in.dat;
     end if;
   end process;
 
diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd
index 83d4ceca..094228ad 100644
--- a/modules/wishbone/wishbone_pkg.vhd
+++ b/modules/wishbone/wishbone_pkg.vhd
@@ -439,8 +439,13 @@ package wishbone_pkg is
       msi_slave_o   : out t_wishbone_slave_out_array (g_num_slaves -1 downto 0));
   end component;
   
-  component xwb_register_link -- puts a register of delay between crossbars
-    port(
+  component xwb_register_link  -- puts a register of delay between crossbars
+    generic (
+      g_WB_IN_MODE         : t_wishbone_interface_mode      := PIPELINED;
+      g_WB_IN_GRANULARITY  : t_wishbone_address_granularity := BYTE;
+      g_WB_OUT_MODE        : t_wishbone_interface_mode      := PIPELINED;
+      g_WB_OUT_GRANULARITY : t_wishbone_address_granularity := BYTE);
+    port (
       clk_sys_i : in  std_logic;
       rst_n_i   : in  std_logic;
       slave_i   : in  t_wishbone_slave_in;
-- 
GitLab