- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I need to add two 32-bit unsigned numbers and need to store in a 33 bit register in VHDL. Is it possible to do so. If so, then please help me to do so. Thanks in advanceLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Hello, I need to add two 32-bit unsigned numbers and need to store in a 33 bit register in VHDL. Is it possible to do so. If so, then please help me to do so. Thanks in advance --- Quote End --- try this: result33bits <= "0"&dataA + dataB; -- assuming all unsigned
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- try this: result33bits <= "0"&dataA + dataB; -- assuming all unsigned --- Quote End --- Thanks, I got the output. I have another doubt. I written the testbench code such that it performs 32 bit addition and stores in a 33 bit register. I am getting these errors in the next clock cycle (Only for 1 time) " Output is not set to default value when enable_i is 0" after I make reset to 0 and "Wrong output" after I make enable to 1. I know that this is because of the clocked process and that I need to define the values of new_mod_s and old_fcw_s whenever the clock is changed, but I don't know where to do these changes. Help me to solve this problem. Thanks in advance. The testbench is as follows:
p_clock_gen :process
begin
clk_128meg_i <= '0';
wait for clk_128meg_i_period/2;
clk_128meg_i <= '1';
wait for clk_128meg_i_period/2;
end process;
--stimulus
p_stim: process
begin
wait for 10 ns;
reset_n_i <= '1';
wait for clk_128meg_i_period;
enable_i <= '1';
fcw_i <= "00000000000000000000000000000000";
mod_i <= "000000000000000000000000";
wait for 50 ns;
fcw_i <= "11111001011110010001000101111111"; -- 4185461119
mod_i <= "110100001101110111010000"; -- 13688272
wait for 50 ns;
fcw_i <= "10101011010101010101110101010111"; -- 2874498391
mod_i <= "000101110111011101101011"; -- 1537899
wait for 50 ns;
fcw_i <= "11001011101101101110101011011101"; -- 3417762525
mod_i <= "000000100010110110110110"; -- 142774
wait for 50 ns;
fcw_i <= "00101010101010101011010100101001"; -- 715830569
mod_i <= "101010101011010101010101"; -- 11187541
wait for 50 ns;
fcw_i <= "11111111111111111111111111111111"; -- 4294967295
mod_i <= "111111111111111111111111"; -- 16777215
wait for 10 ms;
reset_n_i <= '0';
wait for 1 ms;
reset_n_i <= '1';
wait for 1 ms;
enable_i <= '0';
wait for 1 ms;
enable_i <= '1';
wait for 1 ms;
assert false report " End of the simulation" severity Failure;
end process;
new_mod_s <= std_logic_vector("000000" & mod_i & "000");
old_fcw_s <= std_logic_vector("0" & fcw_i);
delay_rst_s <= reset_n_i after 1 ns;
p_fcw_chk: process(delay_rst_s, clk_128meg_i)
begin
if (delay_rst_s = '0') then
assert fcw_mod_o = "000000000000000000000000000000000" report "Output is not set to default value when reset_n_i is 0" severity error;
elsif (clk_128meg_i'event and clk_128meg_i = '0') then
if (enable_i = '1') then
assert fcw_mod_o = std_logic_vector(unsigned(old_fcw_s) + unsigned(new_mod_s)) report "Wrong output" severity error;
else
assert fcw_mod_o = "000000000000000000000000000000000" report "Output is not set to default value when enable_i is 0" severity error;
end if;
end if;
end process;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sory I don't get it. Are you trying to check your design or the testbench. Where is the design?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the design code is here:
entity add1 is
port (reset_n_i : in std_logic; -- global reset
clk_128meg_i : in std_logic; -- 128MHz system clock
enable_i : in std_logic; -- global enable
fcw_i : in std_logic_vector(31 downto 0); -- fractional number with 4 integer bits from MSB and 28 fractional bits (32 bit width)
mod_i : in std_logic_vector(23 downto 0); -- 24 bit fractional number
fcw_mod_o : out std_logic_vector(32 downto 0) -- fcw_i+(5 zeros & mod_i & 3 zeros)
);
end add1;
architecture rtl of add1 is
signal temp_s : std_logic_vector(32 downto 0); -- Register to store the concatenated mod_i value
signal mod_s : std_logic_vector(32 downto 0); -- Register to store the added output (fcw_i+temp_s)
signal fcw_s : std_logic_vector(32 downto 0); -- Register to store the added output (fcw_i)
begin
p_add1 : process( reset_n_i, clk_128meg_i)
begin
if (reset_n_i = '0') then
mod_s <= (others => '0');
elsif (clk_128meg_i'event and clk_128meg_i = '1') then
if (enable_i = '1') then
mod_s <= std_logic_vector(unsigned(fcw_s) + unsigned(temp_s)); -- Adding of fcw_i and temp_s results in mod_s
else
mod_s <= (others => '0');
end if;
end if;
end process;
fcw_s <= std_logic_vector("0" & fcw_i); -- Five zeros are appended to the MSB of mod_i and three zeros are appended to the LSB of mod_i
temp_s <= std_logic_vector("000000" & mod_i & "000"); -- Five zeros are appended to the MSB of mod_i and three zeros are appended to the LSB of mod_i
fcw_mod_o <= std_logic_vector(mod_s);
end rtl;
Sorry for not uploading in the beginning
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the design code is here:
entity add1 is
port (reset_n_i : in std_logic; -- global reset
clk_128meg_i : in std_logic; -- 128MHz system clock
enable_i : in std_logic; -- global enable
fcw_i : in std_logic_vector(31 downto 0); -- fractional number with 4 integer bits from MSB and 28 fractional bits (32 bit width)
mod_i : in std_logic_vector(23 downto 0); -- 24 bit fractional number
fcw_mod_o : out std_logic_vector(32 downto 0) -- fcw_i+(5 zeros & mod_i & 3 zeros)
);
end add1;
architecture rtl of add1 is
signal temp_s : std_logic_vector(32 downto 0); -- Register to store the concatenated mod_i value
signal mod_s : std_logic_vector(32 downto 0); -- Register to store the added output (fcw_i+temp_s)
signal fcw_s : std_logic_vector(32 downto 0); -- Register to store the added output (fcw_i)
begin
p_add1 : process( reset_n_i, clk_128meg_i)
begin
if (reset_n_i = '0') then
mod_s <= (others => '0');
elsif (clk_128meg_i'event and clk_128meg_i = '1') then
if (enable_i = '1') then
mod_s <= std_logic_vector(unsigned(fcw_s) + unsigned(temp_s)); -- Adding of fcw_i and temp_s results in mod_s
else
mod_s <= (others => '0');
end if;
end if;
end process;
fcw_s <= std_logic_vector("0" & fcw_i); -- Five zeros are appended to the MSB of mod_i and three zeros are appended to the LSB of mod_i
temp_s <= std_logic_vector("000000" & mod_i & "000"); -- Five zeros are appended to the MSB of mod_i and three zeros are appended to the LSB of mod_i
fcw_mod_o <= std_logic_vector(mod_s);
end rtl;
Sorry for not uploading in the beginning
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
so is your question why when enable is '0' the value of mod_s doesn't default zero?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yes, exactly
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is nothing wrong with adder logic.
your problem possibly lies in the clock edge delay issues in your testbench (possibly delta delay issue). i.e. the eye tells you clock edge samples the change but in reality there is delta delay. make sure the signal transitions occur as intended relative to clock edge- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, got it. How to write some randomized inputs for this testbench a kind of a loop I mean
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Ok, got it. How to write some randomized inputs for this testbench a kind of a loop I mean --- Quote End --- opion1 : manual successive assignments as you do but care is needed to check delay issues, use multiple of clock periods for delay. option2 : use clocked process to read from array or run prbs. The clocked process guarantees no delay issues relative to edge
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you please give an example with a while loop doing so, because I don't need any variable to do this
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Ok, got it. How to write some randomized inputs for this testbench a kind of a loop I mean --- Quote End --- This a prbs(25 downto 1):
process(reset, clk)
begin
if(reset = '1')then
shift_reg <= '0' & x"00F0F1";
elsif(rising_edge(clk))then
shift_reg(1) <= shift_reg(25) xor shift_reg(22);
shift_reg(25 downto 2) <= shift_reg(24 downto 1);
end if;
end process;
then: assign fcw_i with some 32 bits (mix as you like) and assign mod_i 24 bits (choose your favourite bits) from shift_reg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- This a prbs(25 downto 1):
process(reset, clk)
begin
if(reset = '1')then
shift_reg <= '0' & x"00F0F1";
elsif(rising_edge(clk))then
shift_reg(1) <= shift_reg(25) xor shift_reg(22);
shift_reg(25 downto 2) <= shift_reg(24 downto 1);
end if;
end process;
then: assign fcw_i with some 32 bits (mix as you like) and assign mod_i 24 bits (choose your favourite bits) from shift_reg --- Quote End --- Thats more of a logical approach. If you want a more programatical approach, VHDL has a built in random number generator:
use ieee.math_real.all; -- for the uniform procedure;
signal input : unsigned(7 downto 0);
process
variable seed1, seed2 : positive := 632165687; -- pick any positive value as a seed
variable rand : real;
begin
wait until rising_edge(clk);
uniform(seed1, seed2, rand);
ip <= to_unsigned( integer((rand * real(2**input'length)), input'length); --makes random integer from 0 to 255
end process;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks,
I have written the test bench accordingly and it looks like this:p_rand_gen: process
variable s1_v, s2_v: positive;
variable rand_v: real;
variable fcw_v : real := 40000.0;
variable mod_v : real := 1600.0;
begin
wait for 25 ns;
uniform(s1_v,s2_v,rand_v);
rand_mod_s <= integer (rand_v*fcw_v);
rand_fcw_s <= integer(rand_v *mod_v);
wait for 10 ns;
end process;
--stimulus
p_stim: process
begin
wait for 10 ns;
reset_n_i <= '1';
wait for 15 ns;
enable_i <= '1';
fcw_i <= std_logic_vector(to_unsigned(rand_fcw_s , 32));
mod_i <= std_logic_vector(to_unsigned(rand_mod_s, 24));
wait for 10 ms;
reset_n_i <= '0';
wait for 1 ms;
reset_n_i <= '1';
wait for 1 ms;
enable_i <= '0';
wait for 1 ms;
enable_i <= '1';
wait for 10 ms;
assert false report " End of the simulation" severity Failure;
end process;
delay_rst_s <= reset_n_i after 1 ns;
p_fcw_chk: process(delay_rst_s, clk_128meg_i)
begin
if (delay_rst_s = '0') then
assert fcw_mod_o = "000000000000000000000000000000000" report "Output is not set to default value when reset_n_i is 0" severity error;
elsif (clk_128meg_i'event and clk_128meg_i = '0') then
if (enable_i = '1') then
new_mod_s <= std_logic_vector("000000" & mod_i & "000");
old_fcw_s <= std_logic_vector("0" & fcw_i);
assert fcw_mod_o = std_logic_vector(unsigned(old_fcw_s) + unsigned(new_mod_s)) report "Wrong output" severity error;
else
assert fcw_mod_o = "000000000000000000000000000000000" report "Output is not set to default value when enable_i is 0" severity error;
end if;
end if;
end process;
What I need to do is that, when the variables rand_mod_v and rand_fcw_v are updated, they should reflect the change at once in fcw_i and mod_i which I have written in the "stimuli: process", But its not getting updated. I don't know why. Thanks in advance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Tricky,
Thanks a lot. I have posted the problem previously. What I need to do is I need to update the values of fcw_i and mod_i after every 10 ns (ie, whenever the values of rand_mod_v and rand_fcw_v are updated). Please help me out to solve this problem. I am getting really frustrated- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- What I need to do is that, when the variables rand_mod_v and rand_fcw_v are updated, they should reflect the change at once in fcw_i and mod_i which I have written in the "stimuli: process", But its not getting updated. I don't know why. Thanks in advance --- Quote End --- Thats because you have only assigned them once in the p_stim process, so they will have whatever value is on rand_fcw_s and rand_mod_s. Because both processes are meant to execute code at exactly the same time, they will take the initial values of the rand signals. You need a loop in your p_stim process to update the signals. why not just ditch the p_rand_gen process altogether and ut the random generation in the p_stim process?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I try to join the p_rand_num process along with p_stim process, then the values are not updated. Can you help me how to write a loop within the p_stim process to perform this operation. Please help me
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--stimulus
p_stim: process
variable s1_v, s2_v: positive;
variable rand_v: real;
variable fcw_v : real := 40000.0; -- Why are these variables and not constants?
variable mod_v : real := 1600.0; -- Why are these variables and not constants?
begin
wait for 10 ns;
reset_n_i <= '1';
wait for 15 ns;
enable_i <= '1';
for i in 1 to N_INPUTS loop
uniform(s1_v,s2_v,rand_v);
rand_fcw_s <= integer(rand_v*mod_v);
rand_mod_s <= integer(rand_v*fcw_v);
fcw_i <= std_logic_vector(to_unsigned(rand_v*mod_v, 32));
mod_i <= std_logic_vector(to_unsigned(rand_v*fcw_v, 24));
wait until rising_edge(clk) -- much better to synchronise to the clock rather than waiting for a time period
end loop;
wait for 10 ms;
reset_n_i <= '0';
wait for 1 ms;
reset_n_i <= '1';
wait for 1 ms;
enable_i <= '0';
wait for 1 ms;
enable_i <= '1';
wait for 10 ms;
assert false report " End of the simulation" severity Failure;
end process;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Tricky,
That came out pretty much well. Bit relaxed right now.- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page