I am new to VHDL and FPGA and have been been trying to generate a sine wave by outputting the data from ROM. The ROM is single port and was generated using IP. The sine wave values were stored in a .Mif as signed decimals. When i read the ROM values it outputs my signed values as unsigned. I have tried converting the output from the ROM to signed but that didn't seem to work. Does anyone have any idea how to rectify this? At the moment i just have positive cycles of the sine wave showing in modelsim.Any help would be appreciated Kind regards,
It's always helpful to post your code when asking a question like this. In this case the mif file would also be helpful.You should be able to take the std_logic_vector output of the ROM and convert is to signed using:
... signal rom_out : std_logic_vector(15 downto 0); signal sin_val : signed(15 downto 0); ... sin_val <= signed(rom_out);Normally, if a signed is inadvertently treated as unsigned, the negative parts will appear raised above zero. It sounds like you've somehow taken the absolute value. So to rectify your problem you need to stop rectifying it :-). Although it's good to learn to do it using the wizards, another way is to infer a ROM. This makes for much more maintainable code. You can get a template by right clicking in a VHDL file and selecting "Insert Template ..." and then VHDL -> Full Designs -> RAMS and ROMs. Their example uses an array of std_logic_vectors, but you can use an array of signed and avoid the need for casting. You should always check the fitter report to make sure the tools are doing what you want. Inference can be very finicky. For example, I once tried to infer a ROM as an array of VHDL records. Worked great. Except for one thing. When I checked the fitter report, it was using twice as many M9K's as it needed to because it put each field (I had two) of the VHDL record into a separate M9K. The tools were both smart in that they inferred code that functioned correctly and stupid in that they did not flatten out the record. Always check your reports.
imho the values are stored e.g. as 16Bit vectors only. Especially as the ROM instantiation ports are "std_logic_vector (width-1 downto 0)". These are just '1' and '0'... whether these are interpreted as signed or unsigned depends on your code and the libraries you are using... If you are using IEEE.std_numeric.all, you declare the vectors as signed and unsigned and thus can "convert" the output of the ROM (std_logic_vector) using "to_signed" function when assigning the ROM Output to the vector.If you are using std_logic_signed or std_logic_unsigned (Synopsys libraries), you need to "handle" signed or unsigned by yourself, e.g. when applying arithmetics etc.