Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated code canot be compiled with VHDL 93 only tools. #1

Closed
ppisa opened this issue Jan 6, 2019 · 2 comments
Closed

Generated code canot be compiled with VHDL 93 only tools. #1

ppisa opened this issue Jan 6, 2019 · 2 comments

Comments

@ppisa
Copy link

ppisa commented Jan 6, 2019

This is problem because basic level of Intel Quartus provides only partial support for VHDL 2008.
Full support is available only in paid PRO tools. Xilinx Vivado (as of 2018 version) supports
required features of VHDL 2008 but wne code is used in component then VHDL 2008
attribute cannot be passed from IP Package Editor to main project.

File templates/memory_reg.vhd causes nex error in Quartus

  "generic data_width cannot be used in its own interface list"
@ppisa
Copy link
Author

ppisa commented Jan 6, 2019

When definition of memory_reg component is changed to use std_logic_vector without
defined index range for data_mask, reset_value and auto_clear generics then
literal constant is interpreted as array with ascending range which is counterintuitive
when masks should be generated in this order. Solution is to add function which
examines if input is array with ascending index range and in such case modify
masks indexing.

diff memory_reg.vhd generated/memory_reg.vhd
index 1da3851..3778de0 100644
--- generated/memory_reg.vhd
+++ generated/memory_reg.vhd
@@ -46,17 +46,17 @@ entity memory_reg is
 
         -- Data mask. Each logic 1 indicates present bit, logic 0 indicates
         -- reserved bit in register bits. Reserved bit always returns 0.
-        constant data_mask            :     std_logic_vector(data_width - 1 downto 0);
+        constant data_mask            :     std_logic_vector;
 
         -- Reset polarity
         constant reset_polarity       :     std_logic := '0';
 
         -- Reset value of register
-        constant reset_value          :     std_logic_vector(data_width - 1 downto 0);
+        constant reset_value          :     std_logic_vector;
 
         -- If given bit of the register should be cleared automatically one
         -- clock cycle after writing.
-        constant auto_clear           :     std_logic_vector(data_width - 1 downto 0)
+        constant auto_clear           :     std_logic_vector
     );
     port(
         ------------------------------------------------------------------------
@@ -84,6 +84,17 @@ end entity memory_reg;
 
 architecture rtl of memory_reg is
 
+    pure function bit_in_mask(mask_vec: std_logic_vector; bit_pos : natural)
+                                        return std_ulogic is
+    begin
+       if mask_vec'ascending then
+           return mask_vec(mask_vec'length - 1 - bit_pos);
+       else
+           return mask_vec(bit_pos);
+       end if;
+       --return mask_vec(bit_pos);
+    end function bit_in_mask;
+
     -- Register implementation itself!
     signal reg_value_r          :   std_logic_vector(data_width - 1 downto 0);
 
@@ -112,16 +123,16 @@ begin
     -- Register instance
     ----------------------------------------------------------------------------
     bit_gen : for i in 0 to data_width - 1 generate
-    
+
         ------------------------------------------------------------------------
         -- Register implementation itself
         ------------------------------------------------------------------------
-        reg_present_gen : if (data_mask(i) = '1') generate
+        reg_present_gen : if (bit_in_mask(data_mask, i) = '1') generate
 
             reg_access_proc : process(clk_sys, res_n)
             begin
                 if (res_n = reset_polarity) then
-                    reg_value_r(i)  <= reset_value(i);
+                    reg_value_r(i)  <= bit_in_mask(reset_value, i);
 
                 elsif (rising_edge(clk_sys)) then
 
@@ -131,8 +142,9 @@ begin
 
                     -- Clear the register if autoclear is set and register is
                     -- set
-                    elsif (auto_clear(i) = '1' and reg_value_r(i) = '1') then
-                        reg_value_r(i)  <= reset_value(i);
+                    elsif (bit_in_mask(auto_clear, i) = '1' and
+                           reg_value_r(i) = '1') then
+                        reg_value_r(i)  <= bit_in_mask(reset_value, i);
                     end if;
 
                 end if;
@@ -144,8 +156,8 @@ begin
         -----------------------------------------------------------------------
         -- Registers which are not present are stuck at reset value
         -----------------------------------------------------------------------
-        reg_not_present_gen : if (data_mask(i) = '0') generate
-            reg_value_r(i)    <=  reset_value(i);
+        reg_not_present_gen : if (bit_in_mask(data_mask, i) = '0') generate
+            reg_value_r(i)    <=  bit_in_mask(reset_value, i);
         end generate reg_not_present_gen;
 
     end generate bit_gen;

@Blebowski
Copy link
Owner

Hi, your patch was applied to "memory_reg.vhd" template. Now it should be supported by non-VHDL2008
tools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants