How to detect compiler - vhdl
I have to load ROM from file. Quartus can use .mif files directly and for the simulator I have written (a quick and dirty) .mif file parser with the help of textio. Is there a way to detect Synthesizer tools (Quartus in my case) and to generate textio file loader process only if it is not being compiled by the Synthesizer tool?
(the source question)
You can detect the synthesis tool by using a pragma that is only accepted by your specific synthesis tool. For example, you can write:
constant isQuartus : std_logic := '1'
-- altera translate_off
and '0'
-- altera translate_on
;
This constant will be '1' only if you synthesize this using Altera's Quartus.
More about the various VHDL metacomment pragma's at: http://www.sigasi.com/content/list-known-vhdl-metacomment-pragmas
Are you trying to infer ROMs from your code? If you're using the LPM functions, everything should "just work".
I use ROMs in Quartus and ModelSim without issue. Just create a custom VHDL file for your ROM using the MegaWizard plugin and direct it to the appropriate initialization file, or directly instantiate an altsyncram component and include the init_file generic.
Then compile or simulate as normal. I have had no problems running simulations using ModelSim (Altera version or stand-alone version) with initialized ROMs, and have not had to write any initialization code to read *.mif or *.hex files.
For reference, here is a directly instantiated ROM megafunction from a bit of my code that simulates properly in ModelSim (note the init_file generic):
-- Sine lookup table
sine_lut : altsyncram
generic map (
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "./video/sine_rom-512x8.mif",
intended_device_family => "Arria GX ",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 512,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
widthad_a => 9,
width_a => 8,
width_byteena_a => 1
)
port map (
-- Read port
clock0 => clk,
address_a => sine_addr,
q_a => sine_do
);
If you really need to do something different when simulating vs. synthesizing, there are a several ways to go about it. For simple things, you can use something like the following directives:
--synthesis translate-off
<code for simulation only>
--synthesis translate-on
http://quartushelp.altera.com/11.1/master.htm#mergedProjects/hdl/vhdl/vhdl_file_dir_translate.htm?GSA_pos=5&WT.oss_r=1&WT.oss=--%20synthesis%20translate_off
You should be able to find a lot of real-world examples of these directives via internet search, and I've included one example below (power-on reset is shorter when simulating vs. when running in real hardware):
-- Async. Power-on Reset, with de-assertion delay
process (clk)
begin
if rising_edge (clk) then
-- Create a delay at power-up
if rst_PowerOn='1' then
rst_pora <= '1';
rst_por_cnt <= (others=>'0');
-- synthesis translate_off
elsif rst_por_cnt(5)='1' then -- 256 nS in simulation
rst_pora <= '0';
-- synthesis translate_on
elsif rst_por_cnt(19)='1' then -- 4ms in real hardware
rst_pora <= '0';
else
rst_por_cnt <= rst_por_cnt + 1;
end if;
end if;
end process;
For more complex situations, use your imagination. Some folks use the C pre-processor, the M4 macro language, or something similar as a preliminary build step prior to synthesis/simulation. I have makefiles and scripts that convert FileName.sim.vhdl (for simulation) into FileName.vhdl (for synthesis), processing it with some text utilities to comment/un-comment various blocks of code based on rules I crafted so I could maintain both versions in a single file (think something like an enhanced C pre-processor tweaked for use with VHDL). Just do something that fits with your workflow and team dynamics/culture.
Related
ERROR:Xst:1534 - Sequential logic for node <rx_data> appears to be controlled by multiple clocks
I am new to VHDL and writing program for receiving the serial data, which is dependent on 2 clocks and one RESET signal. One is FPGA's main source clock and another one is the external SPI master clock. The written is like below: process(reset, main_clk, ext_clk) begin if(reset = '0') then rx_data <= x"0000"; elsif(chip_sel = '0') then if(ext_clk'event and ext_clk = '1') then -- rx_data <= rx_data; if(main_clk'event and main_clk = '1') then --- receiving data serially But Xilinx tool is giving error: ERROR:Xst:1534 - Sequential logic for node <rx_data> appears to be controlled by multiple clocks. How to overcome this error?
It's because you use 'event on ext_clk and main_clk which the tools use to infer clocks. Your design should only be sensitive to main_clk and reset. De
How generate sine wave with vhdl?
I am a beginner in vhdl, I am trying to generate a sinus and square singal with a frequency of 50 Mhz, but first i'm trying to generate the sinus wave. I saw a lot of tutorials but it was quite complicated to understand. Here is the code I made. Thank you in advance for your help :) Indications library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_ARITH.ALL; entity sinus is port(clk : in std_logic; clear : in std_logic; sel : in std_logic_vector(1 downto 0); Dataout : out std_logic_vector(7 downto 0)); end sinus; architecture Behavioral of sinus is signal in_data : std_logic_vector(Dataout'range); signal i : integer range 0 to 77:=0; TYPE mem_data IS ARRAY (0 TO 255) OF integer range -128 to 127; constant sin : mem_data := ( ( 0),( 3),( 6),( 9),( 12),( 15),( 18),( 21),( 24),( 28),( 31),( 34),( 37),( 40),( 43),( 46), ( 48),( 51),( 54),( 57),( 60),( 63),( 65),( 68),( 71),( 73),( 76),( 78),( 81),( 83),( 85),( 88), ( 90),( 92),( 94),( 96),( 98),( 100),( 102),( 104),( 106),( 108),( 109),( 111),( 112),( 114),( 115),( 117), ( 118),( 119),( 120),( 121),( 122),( 123),( 124),( 124),( 125),( 126),( 126),( 127),( 127),( 127),( 127),( 127), ( 127),( 127),( 127),( 127),( 127),( 127),( 126),( 126),( 125),( 124),( 124),( 123),( 122),( 121),( 120),( 119), ( 118),( 117),( 115),( 114),( 112),( 111),( 109),( 108),( 106),( 104),( 102),( 100),( 98),( 96),( 94),( 92), ( 90),( 88),( 85),( 83),( 81),( 78),( 76),( 73),( 71),( 68),( 65),( 63),( 60),( 57),( 54),( 51), ( 48),( 46),( 43),( 40),( 37),( 34),( 31),( 28),( 24),( 21),( 18),( 15),( 12),( 9),( 6),( 3), ( 0),( -3),( -6),( -9),( -12),( -15),( -18),( -21),( -24),( -28),( -31),( -34),( -37),( -40),( -43),( -46), ( -48),( -51),( -54),( -57),( -60),( -63),( -65),( -68),( -71),( -73),( -76),( -78),( -81),( -83),( -85),( -88), ( -90),( -92),( -94),( -96),( -98),(-100),(-102),(-104),(-106),(-108),(-109),(-111),(-112),(-114),(-115),(-117), (-118),(-119),(-120),(-121),(-122),(-123),(-124),(-124),(-125),(-126),(-126),(-127),(-127),(-127),(-127),(-127), (-127),(-127),(-127),(-127),(-127),(-127),(-126),(-126),(-125),(-124),(-124),(-123),(-122),(-121),(-120),(-119), (-118),(-117),(-115),(-114),(-112),(-111),(-109),(-108),(-106),(-104),(-102),(-100),( -98),( -96),( -94),( -92), ( -90),( -88),( -85),( -83),( -81),( -78),( -76),( -73),( -71),( -68),( -65),( -63),( -60),( -57),( -54),( -51), ( -48),( -46),( -43),( -40),( -37),( -34),( -31),( -28),( -24),( -21),( -18),( -15),( -12),( -9),( -6),( -3)); begin process(clk, clear) begin if (clear='1') then in_data <= (others => '0'); elsif (clk'event and clk='1') then in_data <= in_data +1; end if; end process; process (in_data(3)) begin if (in_data(3)'event and in_data(3)='1') then in_data <=conv_std_logic_vector(sin(i).8); i<=i+1; if (i=77) then i<=0; end if; end if; end process; process(in_data, sel) begin case sel is when "00" =>Dataout<=in_data; when others =>Dataout<= "00000000"; end case; end process; end Behavioral;
Thanks for the diagram. Because VHDL is hardware description language, the question you should ask yourself is : what do I want to implement ? where are the entity ports, the internal signals on this block diagram ? The main issue you face is that you've no real correspondence between your design and your illustration. Moreover your VHDL coding style needs improvement both regarding the VHDL language itself and how you implement things. Start by replacing use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_ARITH.ALL; by use IEEE.NUMERIC_STD.ALL; This is the official vendor-agnostic VHDL package for signed and unsigned types. IEEE.STD_LOGIC_UNSIGNED and STD_LOGIC_ARITH.ALL are outdated vendor-dependent VHDL packages provided at a time where vendors couldn't agree on a common definition. This led to a lot of portability issues when having a design flow with tools from different vendors (Cadence, Mentor, Synopsys). The IEEE specification body solved once and for all this issue. If you're designing real hardware, the following code can lead to implementation problems process(clk, clear) begin if (clear='1') then in_data <= (others => '0'); elsif (clk'event and clk='1') then in_data <= in_data +1; end if; end process; Your in_data signal is asynchronously cleared but synchronously set. As you don't control when the clear signal will be asserted relative to the clk rising edge, there is a risk of in_data metastability or even that some bits of the in_data remains in reset while the others capture a new value. For a description of the various ways to implement the reset Xilinx has a well documented white paper (WP272) which provides some guidelines useful for any synchronous design be it ASIC or FPGA, Xilinx or Altera. By the way if you have a look, for example, to the widely popular AMBA specifications (AHB, AXI, AXI-Stream, ...), their reset is asserted asynchronously but deasserted synchronously. Personnally, following Xilinx guidelines, I distribute an asynchronous reset through the entire design and generate locally a synchronous reset with the following piece of code (being locally avoid the fanout issue of a system-wide synchronous reset) if (p_reset_n = '0') then s_reset_on_clock <= (others => '1'); else if rising_edge(p_clock) then s_reset_on_clock <= '0' & s_reset_on_clock(3 downto 1); end if; end if; s_reset_on_clock(0) is now your local synchronous reset signal that you can use like any other signal within the synchronous code block. Please replace the old fashioned elsif (clk'event and clk='1') then with elsif rising_edge(clk) then it will be more obvious what's going on here. You say that you want to generate a 50MHz signal but you don't say what the system frequency (or maybe I should understand it the other way around). The ratio system clock frequency / 50MHz will give you the sequence length. Anyway, you will need to declare a free running counter as signal, let's call it counter (in your original code you have two signals, i and in_data, for this same purpose), and reset/increment it using your locally synchronous reset and your clock signal. In case of a square signal (let's say sel = '0'), your output will be solely determined by the value of your counter. Below a given counter value, you'll have a predetermined dataout value (your 'low' state), while above this value, you'll have another predetermined dataout value (your 'high' state). In case of a sine signal (let's say sel = '1'), the counter will represent the phase and will be used as input to your sine lookup table (that you, by the way, could initialize with a VHDL function calculating the lookup table content instead of providing precalculated literals). The output of the sine lookup table is your dataout output. Let me know if you need more help.
block ram (BRAM) read and write using different clocks
I am relatively new to some advanced VHDL programming and have a problem i have been facing for a while. I will try to be very thorough in my problem description. I am using a Digilent Nexys-3 board with SPARTAN - 6 FPGA Here is what i am trying to implement: Read data from ADC SPI bus and store it into the BRAM. For this i instantiate a block RAM using a memory IP core generator ADC_BRAM: bram port map( .. .. addra => addra, dina => ADC_DATA, .. .. ); The addra, ADC_DATA (data on SPI bus stored into a std_logic_vector) is assigned during the "read_adc" state of the FSM in the ADC module. After the ADC has sampled 100 points I stop writing into the BRAM main: process(clk) begin if(rising_edge(clk)) then case state is when read_adc => ..... ..... ..... if(addra < "1100100") then ..... <some code> addra <= addra + 1; ..... elsif (addra = "1100100") then state <= endofconversion; end if; when endofconversion => addra <= "00000000"; wea <= "0"; -- write enable for BRAM state <= read_bram; Next, i want to access the data from the BRAM and send it using USB-UART. From what i understand all the BRAM's are synchronous and thus have to be implemented with process(clk,reset). Currently i have implemented the state " read_bram" under the same process as mentioned above main: process(clk) begin if(rising_edge(clk)) then case state is <some code> when endofconversion => addra <= "00000000"; wea <= "0"; -- write enable for BRAM state <= read_bram; when read_bram => .... <some code> .... end case; Now the UART clock needs to be much slower than the rate at which ADC has been read. My question is " How do i implement the read operation of the BRAM using a much slower clock, which will ensure proper functioning of the UART" ? I also tried another approach where the BRAM module is defined in the top level file and i send the " addra, ADC_DATA" generated from the ADC module into the port map of the BRAM module. Now, on the top level if i create a slower clock to read the data ("douta") from the BRAM and send it to UART, i need to generate "addra" in this process and send it to BRAM port "addra" This causes issues of " multiple drivers " connected to signal "addra", as its values changes in the "process()" of both the ADC module (faster clock) and the top level module (slower clock). Please help me out. I can provide more info if the problem description is not clear. TLDR; How can i use 2 separate clocks while implementing synchronous memory BRAM - "faster clock => write into BRAM" -- based on ADC sampling rate - " slower clock => read from BRAM" -- based on UART clk (slower BAUD rate than ADC sampling speed)
wait statement must contain condition clause with UNTIL keyword
The following VHDL is to be used to test bench. I keep getting an error on the first wait statement during analysis : "wait statement must contain condition clause with UNTIL keyword" I have several working test benches written this way. I can't seem to find what the error might be. `library IEEE; USE IEEE.std_logic_1164.all; entity case_ex_TB is end; architecture simple_test of case_ex_TB is --- DUT Component Declaration --- component case_ex port( clk, rstN: IN std_logic; color: OUT std_logic_vector(2 downto 0)); end component; --- Signals Declaration --- signal rst, clock: std_logic:='0'; signal color: std_logic_vector(2 downto 0); begin DUT: case_ex --- DUT instantiation --- port map (clk => clock, rstN => rst, color => color); --- Signal's Waves Creation --- rst <= '1','0' after 50 ns, '1' after 2 us; clock_crtate: process begin while rst = '0' loop clock <= '1','0' after 50 ns; wait for 100 ns; end loop; clock <= '1'; wait; end process; end simple_test;`
You get this error because you have set your testbench as the top-level entity in Quartus-II. The top-level entity must remain the component case_ex, and this component must contain synthesizable code. To simulate your testbench, you must configure a testbench. Just klick on the plus-sign before "RTL Simulation" and then "Edit Settings". (Names may differ with Quartus version).
Another thing you could note is that, it's necessary to put this file in as a simulation, following the path: Assignments -> settings -> EDA tool settings -> simulation and naturally, changing adding a testbench. Another thing to note is that, if you want to change the top level entity, you just need to follow in Quartus: Project -> Set as top level entity (in the file you are in) Also, in the Project navigator, be sure that don't miss the fact that you need every single file you need in order for your program to work.
Array of 1-bit-wide memory
I'm using ISE 14.7 and i'm trying to create design with some 1-bit-wide distributed RAM blocks. My memory declaration: type tyMemory is array (0 to MEMORY_NUM - 1) of std_logic_vector(MEMORY_SIZE - 1 downto 0) ; signal Memory: tyMemory := ( others => (others => '0')) ; attribute ram_style : string ; attribute ram_style of Memory : signal is "distributed" ; My code: MemoryGen : for i in 0 to MEMORY_NUM - 1 generate process( CLK ) begin if rising_edge(CLK) then if CE = '1' then DataOut(i) <= Memory(i)(Addr(i)) ; Memory(i)(Addr(i)) <= DataIn(i) ; end if ; end if ; end process ; end generate ; After synthesis i get this warning: WARNING:Xst:3012 - Available block RAM resources offer a maximum of two write ports. You are apparently describing a RAM with 16 separate write ports for signal <Memory>. The RAM will be expanded on registers. How can i forse xst to use distributed memory blocks with size=ARRAY_LENGTH and width=1? I can create and use separate memory component(and is works), but i need more elegant solution.
You need to create an entity that describes a variable length 1-bit wide memory, then use a generate statement to create an array of these. While what you have done would provide the functionality you are asking for in a simulator, most FPGA tools will only extract memory elements if your code is written in certain ways. You can find documentation on what code Xilinx ISE tools will understand as a memory element by selecting the appropriate document for your device here http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_7/ise_n_xst_user_guide_v6s6.htm . Look under 'HDL Coding techniques'. Note that if your memory length is large, you will not be able to get maximum performance from it without adding manual pipelining. I think you will get a synthesis message if your memory exceeds the intended useful maximum length for distributed memories. Assuming you are using a Spartan 6 device, you can find information on what the useful supported distributed memory sizes are here: http://www.xilinx.com/support/documentation/user_guides/ug384.pdf page 52.
This should inferre 16 one bit wide BlockRAMs: architecture ... attribute ram_style : string; subtype tyMemory is std_logic_vector(MEMORY_SIZE - 1 downto 0) ; begin genMem : for i in 0 to MEMORY_NUM - 1 generate signal Memory : tyMemory := (others => '0'); attribute ram_style of Memory : signal is "block"; begin process(clk) begin if rising_edge(clk) then if CE = '1' then Memory(Addr(i)) <= DataIn(i) ; DataOut(i) <= Memory(Addr(i)) ; end if ; end if ; end process ; end generate ; end architecture;