From d514633c860824e1e0ae8e6c9619b1f8b09bc301 Mon Sep 17 00:00:00 2001
From: Mathias Kreider <mkreider@gsi.de>
Date: Wed, 6 Apr 2016 14:17:08 +0200
Subject: [PATCH] add wbgenplus vhdl essentials

---
 modules/wishbone/Manifest.py                 |   3 +-
 modules/wishbone/wbgenplus/Manifest.py       |   5 +
 modules/wishbone/wbgenplus/wb_skidpad.vhd    |  91 ++++++++++
 modules/wishbone/wbgenplus/wbgenplus_pkg.vhd | 170 +++++++++++++++++++
 4 files changed, 268 insertions(+), 1 deletion(-)
 create mode 100644 modules/wishbone/wbgenplus/Manifest.py
 create mode 100644 modules/wishbone/wbgenplus/wb_skidpad.vhd
 create mode 100644 modules/wishbone/wbgenplus/wbgenplus_pkg.vhd

diff --git a/modules/wishbone/Manifest.py b/modules/wishbone/Manifest.py
index 11c9315..6ebc4ae 100644
--- a/modules/wishbone/Manifest.py
+++ b/modules/wishbone/Manifest.py
@@ -20,7 +20,8 @@ modules =  { "local" : [
   "wb_spi_flash",
 	"wb_simple_pwm",
   "wb_i2c_bridge",
-  "wbgen2"
+  "wbgen2",
+  "wbgenplus", 	
   ]}
 
 files = [
diff --git a/modules/wishbone/wbgenplus/Manifest.py b/modules/wishbone/wbgenplus/Manifest.py
new file mode 100644
index 0000000..61622b7
--- /dev/null
+++ b/modules/wishbone/wbgenplus/Manifest.py
@@ -0,0 +1,5 @@
+files = ["wb_skidpad.vhd",
+         "wbgenplus_pkg.vhd",
+
+]
+
diff --git a/modules/wishbone/wbgenplus/wb_skidpad.vhd b/modules/wishbone/wbgenplus/wb_skidpad.vhd
new file mode 100644
index 0000000..966a24c
--- /dev/null
+++ b/modules/wishbone/wbgenplus/wb_skidpad.vhd
@@ -0,0 +1,91 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity wb_skidpad is
+generic(
+   g_adrbits   : natural   := 32 --Number of bits in adr
+    
+);
+Port(
+   clk_i        : std_logic;      
+   rst_n_i      : std_logic;             
+  
+   push_i       : in  std_logic;  
+   pop_i        : in  std_logic;  
+   full_o       : out std_logic;  
+   empty_o      : out std_logic;  
+
+   adr_i        : in  std_logic_vector(g_adrbits-1 downto 0);
+   dat_i        : in  std_logic_vector(32-1 downto 0);
+   sel_i        : in  std_logic_vector(4-1 downto 0);  
+   we_i         : in  std_logic;
+
+   adr_o        : out std_logic_vector(g_adrbits-1 downto 0);
+   dat_o        : out std_logic_vector(32-1 downto 0);
+   sel_o        : out std_logic_vector(4-1 downto 0);  
+   we_o         : out std_logic
+ 
+   
+);
+end wb_skidpad;
+
+architecture rtl of wb_skidpad is
+
+  signal s_push0, s_push1, s_pop  : std_logic := '0';
+  signal r_cnt                    : unsigned(1 downto 0) := "11";
+  signal s_inc, s_dec             : unsigned(1 downto 0) := "00";
+  signal s_full, s_empty          : std_logic := '0';
+  signal s_stall                  : std_logic := '0';
+  signal r_buff0, r_buff1, s_buff : std_logic_vector(g_adrbits + 32 + 4 + 1 -1 downto 0) := (others => '0');  
+   
+begin
+
+  s_inc <= "0" & s_push0;
+  s_dec <= (others => (s_pop and not s_empty));   
+
+  s_push0 <= push_i;
+  s_push1 <= s_push0 and not pop_i;
+  s_pop   <= pop_i; 
+
+  s_full <= '1' when r_cnt = "01" 
+        else '0';
+  s_empty <= '1' when r_cnt = "11"
+       else '0';
+
+  mux: with (s_full) select
+  s_buff <= r_buff1 when '1',
+            r_buff0 when others;
+
+  adr_o <= s_buff(37+g_adrbits-1 downto 37);    
+  dat_o <= s_buff(36 downto 5);
+  sel_o <= s_buff(4 downto 1);
+  we_o  <= s_buff(0);  
+
+  full_o <= s_full;
+  empty_o <= s_empty; 
+
+  slave : process(clk_i)
+  begin
+    if rising_edge(clk_i) then
+       if(rst_n_i = '0') then
+          r_buff0    <= (others => '0');
+          r_buff1    <= (others => '0');
+          r_cnt      <= (others => '1');
+       else
+          
+          if (s_push0 = '1') then
+            r_buff0 <= adr_i & dat_i & sel_i & we_i;
+          end if;
+
+          if (s_push1 = '1') then
+            r_buff1  <= r_buff0;
+          end if;
+          
+          r_cnt <= r_cnt + s_inc + s_dec;
+                          
+       end if; -- rst
+    end if; -- clk edge
+  end process;
+
+end rtl;
diff --git a/modules/wishbone/wbgenplus/wbgenplus_pkg.vhd b/modules/wishbone/wbgenplus/wbgenplus_pkg.vhd
new file mode 100644
index 0000000..dd39c5a
--- /dev/null
+++ b/modules/wishbone/wbgenplus/wbgenplus_pkg.vhd
@@ -0,0 +1,170 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package wbgenplus_pkg is
+
+  component wb_skidpad is
+  generic(
+     g_adrbits   : natural   := 32 --Number of bits in adr
+  );
+  Port(
+     clk_i        : std_logic;
+     rst_n_i      : std_logic;             
+    
+     push_i       : in  std_logic;
+     pop_i        : in  std_logic;
+     full_o       : out std_logic;
+     empty_o      : out std_logic;  
+
+     adr_i        : in  std_logic_vector(g_adrbits-1 downto 0);
+     dat_i        : in  std_logic_vector(32-1 downto 0);
+     sel_i        : in  std_logic_vector(4-1 downto 0);  
+     we_i         : in  std_logic;
+
+     adr_o        : out std_logic_vector(g_adrbits-1 downto 0);
+     dat_o        : out std_logic_vector(32-1 downto 0);
+     sel_o        : out std_logic_vector(4-1 downto 0);  
+     we_o         : out std_logic
+   
+     
+  );
+  end component;
+
+  type matrix is array(natural range <>, natural range <>) of std_logic;
+
+  -- assign row
+
+  function mrst(slm : matrix) return matrix;
+
+  -- assign row
+
+  ---function mset(slm : matrix; slv : std_logic_vector; rowindex : natural) return matrix;
+
+  procedure mset(signal slm : out matrix; slv : std_logic_vector; rowindex : natural);
+
+  procedure mset_no_rng(signal slm : out matrix; slv : std_logic_vector; rowindex : natural);
+
+  -- get std logic vector from matrix row
+
+  function mget(slm : matrix; rowindex : natural) return std_logic_vector;
+
+  -- flatten matrix to std logic vector
+
+  function mflat(slm : matrix) return std_logic_vector;
+
+  -- inflate std logic vector to matrix 
+  function minfl(slm : matrix; slv : std_logic_vector ) return matrix;
+
+  --  inflate std logic vector to m x n matrix
+
+  function minflmn(slv : std_logic_vector; col_len : natural; row_len : natural) return matrix;
+
+end wbgenplus_pkg;
+
+package body wbgenplus_pkg is
+
+  function mrst(slm : matrix) return matrix is
+    variable res : matrix(slm'length(1)-1 downto 0, slm'length(2)-1 downto 0);
+    variable row, col : natural := 0;      
+    constant row_len : natural := slm'length(2);
+    constant col_len : natural := slm'length(1);
+  begin
+    for row in 0 to col_len-1 loop
+      for col in 0 to row_len-1 loop
+        res(row, col) := '0';
+      end loop;
+    end loop;
+    return res;		
+  end function;
+
+  
+  procedure mset(signal slm : out matrix; slv : std_logic_vector; rowindex : natural) is
+    variable i : natural := 0;
+  begin
+    for i in slv'range loop
+      slm(rowindex, i) <= slv(i);
+    end loop;	
+  end procedure;
+
+  procedure mset_no_rng(signal slm : out matrix; slv : std_logic_vector; rowindex : natural) is
+    variable i : natural := 0;
+    variable j : natural := 0;
+  begin
+    j := 0;
+    for i in slv'range loop
+      slm(rowindex, j) <= slv(i);
+      j := j+1;
+    end loop;	
+  end procedure;
+  
+
+  -- set matrix row
+--     function mset(slm : matrix; slv : std_logic_vector; rowindex : natural) return matrix is
+--      variable i : natural := 0;
+--      variable res : matrix(slm'length(1)-1 downto 0, slm'length(2)-1 downto 0);
+--     begin
+--      res := slm;
+--      for i in slv'range loop
+--        res(rowindex, i) := slv(i);
+--      end loop;
+--      return res;		
+--     end function;
+
+  
+  -- get matrix row
+  function mget(slm : matrix; rowindex : natural) return std_logic_vector is
+    variable i : natural := 0;
+    variable slv : std_logic_vector(slm'high(2) downto 0);
+  begin
+    for i in slv'range loop
+      slv(i)  := slm(rowindex, i);
+    end loop;
+    return slv;
+  end function;
+
+  
+  -- flatten matrix to std logic vector
+  function mflat(slm : matrix) return std_logic_vector is
+    constant row_len : natural := slm'length(2);
+    constant col_len : natural := slm'length(1);
+    variable res : std_logic_vector(col_len*row_len-1 downto 0);  
+  begin
+    for row in 0 to col_len-1 loop
+      for col in 0 to row_len-1 loop
+        res(row*row_len+col)  := slm(row, col);
+      end loop;
+    end loop;
+    return res;
+  end function;
+
+
+  -- inflate std logic vector to matrix
+  function minfl(slm : matrix; slv : std_logic_vector) return matrix is
+    constant row_len : natural := slm'length(2);
+    constant col_len : natural := slm'length(1);
+    variable res : matrix(slm'length(1)-1 downto 0, slm'length(2)-1 downto 0);
+  begin
+    for row in 0 to col_len-1 loop
+       for col in 0 to row_len-1 loop
+            res(row, col)  := slv(row*row_len+col);
+       end loop;
+    end loop;
+    return res;
+  end function;
+  
+
+  -- -- inflate std logic vector to m*n matrix 
+  function minflmn(slv : std_logic_vector; col_len : natural; row_len : natural) return matrix is
+    variable res : matrix(col_len-1 downto 0, row_len-1 downto 0);
+  begin
+    for row in 0 to col_len-1 loop
+       for col in 0 to row_len-1 loop
+            res(row, col)  := slv(slv'length-1 - (row*row_len+col));
+       end loop;
+    end loop;
+    return res;
+  end function;
+
+
+end wbgenplus_pkg;
-- 
GitLab