Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Hardware Development
- :
- FPGA Configuration
- :
- Re: Math operations on unsigned (adding)

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Mason1

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-29-2020 12:40 PM

539 Views

Registered:
04-03-2020

I was using integers for my VHDL code but then I switched to unsigned because of the feedback I got here. In order to make sure I am doing the right thing, I tried to produce a ramp and send it to my MATLAB plotting code. I wrote the VHDL code in a component, here is the code I have inside the component:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity SinWGen is Port ( spi_adc_cs_b : in std_logic; sin : out unsigned (15 downto 0); cos : out unsigned (15 downto 0); state_param : in integer range 0 to 3); end SinWGen; architecture Behavioral of SinWGen is begin WaveGen: process(spi_adc_cs_b) variable cnt : unsigned (15 downto 0) := (others => '0'); variable tst : unsigned (15 downto 0) := (12 => '1', others => '0'); begin if(rising_edge(spi_adc_cs_b)) then if(state_param = 1) then if(cnt < 4000) then sin <= cnt; cnt:= cnt + 1000; else sin <= (others => '0'); cnt := (others => '0'); end if; end if; end if; end process WaveGen; end Behavioral;

This is the section that I am concerned with:

```
if(rising_edge(spi_adc_cs_b)) then
if(state_param = 1) then
if(cnt < 4000) then
sin <= cnt;
cnt:= cnt + 1000;
else
sin <= (others => '0');
cnt := (others => '0');
end if;
end if;
end if;
```

I expect the output "sin" to be a ramp with 1000 steps which goes to 4000 and then comes back to zero. It goes exactly opposit, starts from 4000, goes down to zero in 1000 steps!

I changed the 4000 and 1000 to unsigned (i.e. "BinaryData") and re-ran the code but the results are the same. So,

- Is this how I should be adding unsigned to another number?

- Is it ok if I use integers for these situations (because they are more straightforward) or do I have to convert my numbers to unsigned?

Thank you in advance for your help.

1 Solution

Accepted Solutions

markg@prosensing.com

Historian

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-30-2020 04:29 PM

411 Views

Registered:
01-22-2015

Some thoughts:

- Your latest VHDL works! That is, cnt will increment as 0, 1000, 2000, 3000, 4000, 0, 1000, 2000, ....
- When working with VHDL unsigned, we tend to write constants using hex notation rather than binary notation - just because it is easier and less prone to error. For example with unsigned(15 downto 0), you have dec(1000) = "0000001111101000" = x"03E8". Many calculators (eg. the one found in MS WIN10) have a "Programmer" setting which makes it easy to convert from decimal to hex notation.
- If Vivado behavioral simulation shows that our VHDL is working then we usually say GREAT and move on.
- There is nothing wrong with using MATLAB to further verify things - but (as you say) there is a communication interface to worry about and somehow MATLAB is converting your unsigned numbers to an ADC voltage? In this case, I think your use of MATLAB is not helping with your FPGA work.

Cheers,

Mark

6 Replies

bruce_karaffa

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-29-2020 12:49 PM

535 Views

Registered:
06-21-2017

Make cnt a signal instead of a variable.

richardhead

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-29-2020 01:38 PM

515 Views

Registered:
08-01-2012

That will make little difference here, as the assignment to cnt is done after the assigned of sin <= cnt; So the cnt will be a register as will sin. The code shows cnt incrementing in steps of 1000 up to 4000

Why are you using the chip select signal as a clock?

Mason1

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-29-2020 02:06 PM

507 Views

Registered:
04-03-2020

Mason1

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-30-2020 11:36 AM

434 Views

Registered:
04-03-2020

I changed the code and converted the variable to signal, I also copied the code into a top module, here is how it looks like now:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Top is Port ( clk : in STD_LOGIC); end Top; architecture Behavioral of Top is signal cnt : unsigned (15 downto 0) := (others => '0'); signal sin : unsigned (15 downto 0); begin WaveGen: process(clk) -- variable cnt : unsigned (15 downto 0) := (others => '0'); variable tst : unsigned (15 downto 0) := (12 => '1', others => '0'); begin if(rising_edge(clk)) then if(cnt < "0000111110100000") then sin <= cnt; cnt<= cnt + "0000001111101000"; else -- sin <= (others => '0'); cnt <= (others => '0'); end if; end if; end process WaveGen; end Behavioral;

Then, I simulated the code. Here are the simulation results:

Which seems correct. But when I run the code and see the results in MATLAB, I see the following (normalized to a 3.3 V reference):

I really think my communication code does not have the capability of flipping the data before sending them. It is quite strange that my staircase has a negative ramp while the simulation shows the opposite. Also,

"0000111110100000" = 4000

"0000001111101000" = 1000

markg@prosensing.com

Historian

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

06-30-2020 04:29 PM

412 Views

Registered:
01-22-2015

Some thoughts:

- Your latest VHDL works! That is, cnt will increment as 0, 1000, 2000, 3000, 4000, 0, 1000, 2000, ....
- When working with VHDL unsigned, we tend to write constants using hex notation rather than binary notation - just because it is easier and less prone to error. For example with unsigned(15 downto 0), you have dec(1000) = "0000001111101000" = x"03E8". Many calculators (eg. the one found in MS WIN10) have a "Programmer" setting which makes it easy to convert from decimal to hex notation.
- If Vivado behavioral simulation shows that our VHDL is working then we usually say GREAT and move on.
- There is nothing wrong with using MATLAB to further verify things - but (as you say) there is a communication interface to worry about and somehow MATLAB is converting your unsigned numbers to an ADC voltage? In this case, I think your use of MATLAB is not helping with your FPGA work.

Cheers,

Mark

Mason1

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

07-07-2020 08:16 AM

355 Views

Registered:
04-03-2020

__As you said, I had a problem with communication.__

I was skipping some samples and jumping to the 3rd next sample instead of the next:

Current sample: #3

Next Sample: #2 (should be #4 but it goes to #4, then #1, then #2)

This gave me a wrong illusion.