Is there a way to suppress a Fatal error in Modelsim? I'm guessing not, but it would be useful at times. Fore example, I've created a multiplier where one input is signed, the other unsigned, and the result of course signed. Quartus can't seem to infer this, so I generate core. Quartus generates a component template:
component dds_mult is port ( result : out std_logic_vector(24 downto 0); dataa_0 : in std_logic_vector(11 downto 0); datab_0 : in std_logic_vector(12 downto 0); clock0 : in std_logic ); end component dds_mult;To avoid type conversions, I always modify this in my code to be:
component dds_mult is port ( result : out signed(24 downto 0); dataa_0 : in unsigned(11 downto 0); datab_0 : in signed(12 downto 0); clock0 : in std_logic ); end component dds_mult;This synthesizes fine and works correctly and even SignalTap is happy. However, Modelsim yells at me giving an error: # ** Fatal: (vsim-3807) Types do not match between component and entity for port "result". It's of course, correct and I can of course add the necessary type conversions to get rid of it. But it's alot of pointless code and I'd prefer to just suppress the error. I'm guessing suppressing fatal errors is not supported (I tried "-suppress 3807") but since I use this alot if would be helpful.
This is because you have a VHDL syntax error, its not a design error. Quartus is quite relaxed in it's VHDL language conformance at times as it is trying to map things to real logic. But Modelsim must stick by the rules or some things just wont work properly. Using different types between the component and the entity is just illegal VHDL (and Im surprised Quartus allowed it). Why not just have unsigned/signed data types on the entity in the first place? std_logic_vector is meant to represent a bus, not arithmatic.And then another option - why even bother using componenets at all? have you ever tried direct entity instantiation, which is been possible for nearly 25 years? it saves having to create all those components and will give you missmatch errors at the compile stage (usually occurs within seconds) rather than at the map stage (which can take several minutes).
--- Quote Start --- Why not just have unsigned/signed data types on the entity in the first place? std_logic_vector is meant to represent a bus, not arithmatic. --- Quote End --- Trick, I probably wasn't clear: Quartus generates the entity with std_logic_vectors when I create a multiplier: https://www.alteraforum.com/forum/attachment.php?attachmentid=14099 I completely agree it would make more sense if the generated code used signed/unsigned, but I don't control it. --- Quote Start --- And then another option - why even bother using componenets at all? have you ever tried direct entity instantiation, which is been possible for nearly 25 years? it saves having to create all those components and will give you missmatch errors at the compile stage (usually occurs within seconds) rather than at the map stage (which can take several minutes). --- Quote End --- As near as I can tell, all the megafunction components (eg altera_mf_components.vhd) use std_logic_vector for everything. Are you saying there is way to directly instantiate say a multiplier with the proper types for each argument. That would be really helpful.
Ok, sorry - slight missunderstanding. But im afraid you're stuck with SLVs if you insist on using the megafunction. But you can still use direct instantiation so you dont need to use a component at all (but type conversions are needed).But you should be able to infer the multipler without needing to generate anything. Why not just append a '0' to the front of your unsigned to make it signed?
ip1 : unsigned(7 downto 0); ip2 : signed(8 downto 0); op : signed(17 downto 0); ... op <= signed('0' & ip1) * ip2;
I finally realized the reason the tools balk at using "*" for an unsigned times a signed is that numeric_std does not have function "*" defined for that case. My first inclination was to emulate numeric_std for that case. Works great in simulation, but for synthesis it gives incorrect answers if the upper bit of the unsigned is set. For example, for two 8 bit numbers, 160 * 2 gave -192 in SignalTap because 160 is "10100000" which is -96.So synthesis is creating a signed * signed and really can't infer a mixed type multiplier. I had resisted your idea in the past since I'm pretty sure I lose a bit in my DSP block. But in practice very few of my multipliers are on the "edge" of the 18x18 or 18x19 boundary and I could handle them specially. It's worth the convenience. I just defined a function:
/* Multiply an unsigned and signed. */ function "*" (L : unsigned; R : signed) return signed is constant PROD_BITS : integer := L'length + R'length; variable XL : signed(L'left + 1 downto 0); -- 1 bit longer than L variable RESULT : signed(PROD_BITS downto 0) := (others => '0'); -- Extra bit begin -- Turn unsigned into a positive signed. XL := signed('0' & L); -- Infer a "signed" * signed mult RESULT := XL * R; -- Only need PROD_BITS of result return RESULT(PROD_BITS - 1 downto 0); end function "*";and can now do things such as your example:
ip1 : unsigned(7 downto 0); ip2 : signed(8 downto 0); op : signed(16 downto 0); -- Extra bit not needed ... op <= ip1 * ip2;Really simplifies code and fitter report confirms it infers a hard multiplier. I used the "technique" of redefining component types in quite a few places in both Xilinx and Altera tools of last 20 years (eg address inputs to RAM as unsigned), but the multipliers were the main issue. Type conversions on inputs are pretty simple.