0
\$\begingroup\$

I have created a 2D RAM block, it is an array of 32 bit std_logic_vectors:

subtype TEST_MEM_DATA_WORD is std_logic_vector(31 downto 0);
type TEST_MEM_DATA_MEM_ARRAY is array (natural range <>) of TEST_MEM_DATA_WORD;
signal TEST_DATA_MEM : TEST_MEM_DATA_MEM_ARRAY (63 downto 0);

Here is the process that is used to read and write it:

 TEST_DATA_MEM_PROC: process(CLK) is
 variable address_int: natural;
 begin
 if rising_edge(CLK) then
 if RESET = '0' then
 TEST_DATA_MEM <= (others=>(others=>'0'));
 TEST_MEMORY_RDATA_OUT <= (others=>'0');
 address_int := 0;
 else
 address_int := to_integer(unsigned(TEST_MEMORY_ADDR_IN)); 
 if TEST_MEMORY_WR_IN = '1' then
 TEST_DATA_MEM (address_int) <= TEST_MEMORY_WDATA_IN; 
 end if;
 if TEST_MEMORY_RD_IN = '1' then
 TEST_MEMORY_RDATA_OUT <= TEST_DATA_MEM (address_int);
 end if;
 end if;
 end if;
 end process;

I want to achieve a scenario where the few address locations of the TEST_DATA_MEM have constant values assigned to them. We are able to read these locations but not able to write these locations. How should this process be changed to achieve this end? There are certainly multiple ways but I want to know the proper way. I think this would be where no registers would have to be synthesized since the value shall remain constant forever.

Putting constant assignment outside the process will clash since there will be 2 drivers into the process. Putting assignment at end of the clocked process is one way to do this. However, I suspect that this shall infer registers since the constant values shall get assigned on the first rising edge of clock and not from time zero.

Using an if statement to check the address value before writing into the memory as another way to ensure that only the value assigned in the process remains. However, as per syntax of VHDL and the typical synthesis tool rules, there must be a way to achieve this without involving an if statement that checks the address value when TEST_MEMORY_WR_IN is '1'.

asked Sep 17, 2020 at 20:28
\$\endgroup\$
3
  • \$\begingroup\$ I don't know if there's a special VHDL feature for this. At my company where we use Verilog we have a separate Python script to auto-generate our register map source files, with generated address-by-address if statements and concatenations as needed. It doesn't synthesize to an optimized RAM cell, just a bunch of registers though. \$\endgroup\$ Commented Sep 17, 2020 at 20:42
  • \$\begingroup\$ This memory shall have to synthesized using logic cells and not BRAM \$\endgroup\$ Commented Sep 17, 2020 at 20:49
  • 1
    \$\begingroup\$ TEST_MEM_DATA_MEM_ARRAY is a single dimensional array it has only one index. Either qualifying writes as you indicate or assigning constant values to the output for specific addresses will prevent locations from being both written and read allowing optimization to remove the constants registers. The latter method is vendor agnostic, diverting some inputs to the read output multiplexer. \$\endgroup\$ Commented Sep 17, 2020 at 21:30

1 Answer 1

3
\$\begingroup\$

Instead of special-casing the writes, do it on the reads. The optimizer will automatically delete any registers that are written but never read.

 if TEST_MEMORY_RD_IN = '1' then
 case address_int is
 when special_address_a => TEST_MEMORY_RDATA_OUT <= special_data_a;
 when special_address_b => TEST_MEMORY_RDATA_OUT <= special_data_b;
 when others => TEST_MEMORY_RDATA_OUT <= TEST_DATA_MEM (address_int);
 end case;
 end if;
answered Sep 17, 2020 at 21:21
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.