Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Gray counter code error

Status
Not open for further replies.

Yaro

Newbie level 6
Joined
Dec 23, 2014
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
99
I've found a Gray Couter code already written for a FIFO code. But it gives me an error.

Here's the code:

Code:
----------------------------------------
-- Function    : Code Gray counter.
-- Coder       : Alex Claros F.
-- Date        : 15/May/2005.
-- Translator  : Alexander H Pham (VHDL)
----------------------------------------
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    use ieee.std_logic_arith.all;
    
entity GrayCounter is
    generic (
        COUNTER_WIDTH :integer := 4
    );
    port (                                  --'Gray' code count output.
        GrayCount_out :out std_logic_vector (COUNTER_WIDTH-1 downto 0);  
        Enable_in     :in  std_logic;       -- Count enable.
        Clear_in      :in  std_logic;       -- Count reset.
        clk           :in  std_logic        -- Input clock
    );
end entity;

architecture rtl of GrayCounter is
    signal BinaryCount :std_logic_vector (COUNTER_WIDTH-1 downto 0);
begin
    process (clk) begin
        if (rising_edge(clk)) then
            if (Clear_in = '1') then
                --Gray count begins @ '1' with
                BinaryCount   <= conv_std_logic_vector(1, COUNTER_WIDTH);  
                GrayCount_out <= (others=>'0');
            -- first 'Enable_in'.
            elsif (Enable_in = '1') then
                BinaryCount   <= BinaryCount + 1;
                GrayCount_out <= (BinaryCount(COUNTER_WIDTH-1) & 
                                  BinaryCount(COUNTER_WIDTH-2 downto 0) xor 
                                  BinaryCount(COUNTER_WIDTH-1 downto 1));
            end if;
        end if;
    end process;
    
end architecture;

The error I've is:

Arguments have widths 4 and 3, they should match on GrayCount_out.

How I can fix this error?
 

the output assignment is 1 bit shorter than COUNTER_WIDTH. Hence the error.

BinaryCount(COUNTER_WIDTH-1) = 1 bit
BinaryCount(COUNTER_WIDTH-2 downto 0) xor BinaryCount(COUNTER_WIDTH-1 downto 1) = COUNTER_WIDTH-2 bits

hence length of output = COUNTER_WIDTH-1 (which is 1 bit too short).
 

Just make this change:

GrayCount_out <=
(BinaryCount(COUNTER_WIDTH-1) & (BinaryCount(COUNTER_WIDTH-2 downto 0) xor BinaryCount(COUNTER_WIDTH-1 downto 1)));
 

Thank you. Now I can synthesize it.

But now I've an additional error when I simulate it:

Code:
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
#    Time: 3617300 ps  Iteration: 2  Instance: aFifo_0/GrayCounter_pWr

# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
#    Time: 3697300 ps  Iteration: 2  Instance: aFifo_0

Can you help me also with this error?

Here's the FIFO code I use with the gray counter:

Code:
------------------------------------------------------------
-- Function : Asynchronous FIFO (w/ 2 asynchronous clocks).
-- Coder    : Alex Claros F.
-- Date     : 15/May/2005.
-- Notes    : This implementation is based on the article 
--            'Asynchronous FIFO in Virtex-II FPGAs'
--            writen by Peter Alfke. This TechXclusive 
--            article can be downloaded from the
--            Xilinx website. It has some minor modifications.
-- Coder     : Deepak Kumar Tala (Verilog)
-- Translator: Alexander H Pham (VHDL)
------------------------------------------------------------
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
entity aFifo is
    generic (
        DATA_WIDTH :integer := 8;
        ADDR_WIDTH :integer := 4
    );
    port (
        -- Reading port.
        Data_out    :out std_logic_vector (DATA_WIDTH-1 downto 0);
        Empty_out   :out std_logic;
        ReadEn_in   :in  std_logic;
        RClk        :in  std_logic;
        -- Writing port.
        Data_in     :in  std_logic_vector (DATA_WIDTH-1 downto 0);
        Full_out    :out std_logic;
        WriteEn_in  :in  std_logic;
        WClk        :in  std_logic;
	 
        Clear_in:in  std_logic
    );
end entity;
architecture rtl of aFifo is
    ----/Internal connections & variables------
    constant FIFO_DEPTH :integer := 2**ADDR_WIDTH;

    type RAM is array (integer range <>)of std_logic_vector (DATA_WIDTH-1 downto 0);
    signal Mem : RAM (0 to FIFO_DEPTH-1);
    
    signal pNextWordToWrite     :std_logic_vector (ADDR_WIDTH-1 downto 0);
    signal pNextWordToRead      :std_logic_vector (ADDR_WIDTH-1 downto 0);
    signal EqualAddresses       :std_logic;
    signal NextWriteAddressEn   :std_logic;
    signal NextReadAddressEn    :std_logic;
    signal Set_Status           :std_logic;
    signal Rst_Status           :std_logic;
    signal Status               :std_logic;
    signal PresetFull           :std_logic;
    signal PresetEmpty          :std_logic;
    signal empty,full           :std_logic;
    
    component GrayCounter is
    generic (
        COUNTER_WIDTH :integer := 4
    );
    port (
        GrayCount_out :out std_logic_vector (COUNTER_WIDTH-1 downto 0);
        Enable_in     :in  std_logic;  --Count enable.
        Clear_in      :in  std_logic;  --Count reset.
        clk           :in  std_logic
    );
    end component;
begin

    --------------Code--------------/
    --Data ports logic:
    --(Uses a dual-port RAM).
    --'Data_out' logic:
    process (RClk) begin
        if (rising_edge(RClk)) then
            if (ReadEn_in = '1' and empty = '0') then
                Data_out <= Mem(conv_integer(pNextWordToRead));
            end if;
        end if;
    end process;
            
    --'Data_in' logic:
    process (WClk) begin
        if (rising_edge(WClk)) then
            if (WriteEn_in = '1' and full = '0') then
                Mem(conv_integer(pNextWordToWrite)) <= Data_in;
            end if;
        end if;
    end process;

    --Fifo addresses support logic: 
    --'Next Addresses' enable logic:
    NextWriteAddressEn <= WriteEn_in and (not full);
    NextReadAddressEn  <= ReadEn_in  and (not empty);
           
    --Addreses (Gray counters) logic:
    GrayCounter_pWr : GrayCounter
    port map (
        GrayCount_out => pNextWordToWrite,
        Enable_in     => NextWriteAddressEn,
        Clear_in      => Clear_in,
        clk           => WClk
    );
       
    GrayCounter_pRd : GrayCounter
    port map (
        GrayCount_out => pNextWordToRead,
        Enable_in     => NextReadAddressEn,
        Clear_in      => Clear_in,
        clk           => RClk
    );

    --'EqualAddresses' logic:
    EqualAddresses <= '1' when (pNextWordToWrite = pNextWordToRead) else '0';

    --'Quadrant selectors' logic:
    process (pNextWordToWrite, pNextWordToRead)
        variable set_status_bit0 :std_logic;
        variable set_status_bit1 :std_logic;
        variable rst_status_bit0 :std_logic;
        variable rst_status_bit1 :std_logic;
    begin
        set_status_bit0 := pNextWordToWrite(ADDR_WIDTH-2) xnor pNextWordToRead(ADDR_WIDTH-1);
        set_status_bit1 := pNextWordToWrite(ADDR_WIDTH-1) xor  pNextWordToRead(ADDR_WIDTH-2);
        Set_Status <= set_status_bit0 and set_status_bit1;
        
        rst_status_bit0 := pNextWordToWrite(ADDR_WIDTH-2) xor  pNextWordToRead(ADDR_WIDTH-1);
        rst_status_bit1 := pNextWordToWrite(ADDR_WIDTH-1) xnor pNextWordToRead(ADDR_WIDTH-2);
        Rst_Status      <= rst_status_bit0 and rst_status_bit1;
    end process;
    
    --'Status' latch logic:
    process (Set_Status, Rst_Status, Clear_in) begin--D Latch w/ Asynchronous Clear & Preset.
        if (Rst_Status = '1' or Clear_in = '1') then
            Status <= '0';  --Going 'Empty'.
        elsif (Set_Status = '1') then
            Status <= '1';  --Going 'Full'.
        end if;
    end process;
    
    --'Full_out' logic for the writing port:
    PresetFull <= Status and EqualAddresses;  --'Full' Fifo.
    
    process (WClk, PresetFull) begin --D Flip-Flop w/ Asynchronous Preset.
        if (PresetFull = '1') then
            full <= '1';
        elsif (rising_edge(WClk)) then
            full <= '0';
        end if;
    end process;
    Full_out <= full;
    
    --'Empty_out' logic for the reading port:
    PresetEmpty <= not Status and EqualAddresses;  --'Empty' Fifo.
    
    process (RClk, PresetEmpty) begin --D Flip-Flop w/ Asynchronous Preset.
        if (PresetEmpty = '1') then
            empty <= '1';
        elsif (rising_edge(RClk)) then
            empty <= '0';
        end if;
    end process;
    
    Empty_out <= empty;
end architecture;
 
Last edited:

I suggest you follow the non-0/1 value back to its source. This usually occurs when values have not been assigned an initial value
 
TrickyDicky is correct. I will just post an answer which I got from Xilinx forum:

"Since these warnings appear at time 0, they probably happen because not all signals have been assigned a useful default value ('0' or '1'). Without that these signals carry 'U', such causing the warning.
Make sure that you assign default values to all signal declarations in your testbench (not in the models!).

If you have tristate signals that start with a 'Z' at the beginning of your simulation, you probably have to live with the warnings.
Having 'X'es in simulation sometimes is unavoidable. But you need to make sure that they don't enter registers and start to loop in feedback paths. That would ultimately corrupt your simulation.

In some situations it may be useful to force the 'X'es back to '0's or '1'es with a function or assignment:
e.g.: mysig_out <= '1' when mysig_in = '1' else '0';
The else brach covers all unwanted inputs and ties the output to '0'.
But be carefully with that, because you are manipulating simulation results.
This may hide true errors and show good results for a faulty circuit. So use with care!"


http://forums.xilinx.com/t5/Simulation-and-Verification/modelsim-simulation-warning/td-p/123812
 

Looking over the code, either NextWriteAddressEn and/or Clear_in are going X, which causes the addition in the GrayCounter_pWr to go X. As this is occurring far after 0 ns in the simulation (3617300 ps). Is this when you release the Clear_in signal in the simulation? I would suggest you add the Clear_in to the full and empty generation as they could be causing the NextWriteAddressEn to go X as they are not initialized.

Have you considered looking at the Cumming's paper on asynchronous FIFO design? What you are using, which was based on the P. Alfke design from earlier was not optimized for performance. The design contains long combinational paths to generate the flags, which reduces the maximum achievable performance.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top