1
\$\begingroup\$

I have initialized a single port BRAM (clk,din,dout,addr,we) 8X10 with .coe file. I want to read from BRAM and write into the 2D array of dimension 10X8. As the dout of BRAM is 8 bit but the width of array is 10 basically, I want to do transpose. Kindly suggest me some solution. Please zoom the image below for better details.

entity dummy_handle is
    Port ( clk : in  STD_LOGIC;
                --test : out STD_LOGIC_VECTOR(7 DOWNTO 0);

           rst : in  STD_LOGIC);
end dummy_handle;

architecture Behavioral of dummy_handle is

type array2D is array (0 to 7,0 to 9) of  STD_LOGIC;
signal M: array2D;
signal addr_array : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";



signal we_A: STD_LOGIC_VECTOR(0 DOWNTO 0) := "0";
signal addr : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";
signal din : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal test : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal dout : STD_LOGIC_VECTOR(7 DOWNTO 0); 
signal i : integer:= 0;
signal j : integer:= 0;

COMPONENT array_print
  PORT (
    clka : IN STD_LOGIC;
    wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
    addra : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
  );
END COMPONENT;

begin
    
    test <= dout;

print_array : array_print
  PORT MAP (
    clka => clk,
    wea => we_A,
    addra => addr,
    dina => din,
    douta => dout
  );


dat_process: process(clk,addr,i,j,test)
begin
        if rising_edge(clk) then
            
        
            
                if j = 9 and addr = "1001" then 
                    addr <= "0000";
                    j <= 0;
                    i <= 0; 
        
                else
                
                
                    M(to_integer(unsigned(addr_array)),j) <= test(i);
                    addr_array <= addr_array + 1;
                    i <= i + 1;
                
                    if addr_array = "111" then
                        j <= j + 1;
                        addr <= addr + 1;
                        addr_array <= "000";
                    end if;
                    
                
                
            
                end if;

        end if;

    end process dat_process;
end Behavioral;

This is my code,it works ok for 0th column of array , but rest of the column upto 9 is showing undefined. It is not updating j.

This is the test bench.

ENTITY dummy_handle_test IS
END dummy_handle_test;
 
ARCHITECTURE behavior OF dummy_handle_test IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT dummy_handle
    PORT(
         clk : IN  std_logic;
         rst : IN  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal rst : std_logic := '0';

   -- Clock period definitions
   constant clk_period : time := 20 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: dummy_handle PORT MAP (
          clk => clk,
          rst => rst
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  

      wait for clk_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;

dout is the out of BRAM, and it is of 8 bit ,how can we make it as a 10 bit and also I am not able to understand the long and short vector point, it will corrupt the original data ,i think.Pls help me in that.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – Voltage Spike
    Dec 11, 2020 at 14:30

1 Answer 1

1
\$\begingroup\$

Answering your first question. I'll edit this as more information is provided. To add a short vector to the contents of a longer vector you can do this:

signal vector_long : std_logic_vector(9 downto 0);
signal vector_short : std_logic_vector(7 downto 0);

#place statement below in process
vector_long <= "00" & vector_short

This snippet will place 00 in vector_long at index 9 & 8 while the value of vector_short is placed in the lower 8 bits.

In your case it would be more convenient to do this:

signal dout : std_logic_vector(9 downto 0) := (others => '0');

#move to component declaration
print_array : array_print
PORT MAP (
  clka => clk,
  wea => we_A,
  addra => addr,
  dina => din,
  douta => dout(7 downto 0)
);

As you can see, we can assign individual bits in the port map. There is also an initial setting on the dout signal so the two uppermost bits are not undefined. This is a simulation only construct and will be removed for synthesis. That is not a problem as in the real world, there are only 2 states in a register.

Other Errors

You have also made an error in the sensitivity list of your process. You only need clock in the sensitivity list (and rst too, if you intend to use it). This will cause very erratic behaviour as the process is run when one of the items in your sensitivity list changes.

As regards your use statements you should remove std_logic_unsigned as a library. It is a deprecated library and is no longer supported. Also, it contains functions with the same name as Numeric_std which will conflict. You need to do type conversions on the signals you are adding to or if you absolutely have to do vector arithmetic then you should use the VHDL-2008 library numeric_std_unsigned.

The next error is that you allow i to count past 7. This will cause a fatal error in simulation when you try to read from test(8) which does not exist. This means that j will never be updated as the simulation will stop. You should have got an error message about this in your simulator. Adding an elsif to check the value of i before reading from test(i) will prevent this. You then need to set i back to 0.

I'm assuming that you only intend to read from BRAM once? As it stands, this process will run over and over as you have not added any controls such as enable.

\$\endgroup\$
3
  • \$\begingroup\$ I had set the BRAM to always enable mode. And want to read from BRAM for every address like first I read from address 0 and put the value to the array at 0th column and for the next column of array I want to read the next i.e. address 1of the BRAM and so on. \$\endgroup\$ Dec 11, 2020 at 13:28
  • \$\begingroup\$ You misunderstand. I was referring to you custom process. Once it has looped through and read the bram, it will begin again, and again, and again. \$\endgroup\$
    – Vance
    Dec 11, 2020 at 14:54
  • \$\begingroup\$ once it reads the last address of BRAM and placed the data to last column of array, i need to stop the process then, for that i am using NULL,Is it correct? \$\endgroup\$ Dec 12, 2020 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.