Search code examples
vhdl

Writing a code for a CRC using D-FlipFlop in VHDL


I'm learning VHDL for a university project. The goal is to write a CRC circuit given a certain polynomial. I found online solution that uses register but I wanted to do it by using actual D-FlipFlop.

So I created the D-FlipFlop and put in my main file several instances of them using generate to be more flexible and be able to add or remove flipflop easily.

library IEEE;
use IEEE.std_logic_1164.all;

entity LFSR is
    generic (NBit   : positive := 8);
    port(
        clk :in     std_logic;
        reset   :in     std_logic;
        din :in     std_logic;
        dout    :out    std_logic_vector(Nbit-1 downto 0)
        );
    end LFSR;
architecture rtl of LFSR is

    component DFC
        port(
            clk :in std_logic;
            reset   :in std_logic;
            d   :in std_logic;
            crc :out    std_logic;
            q   :out    std_logic
        );  
    end component DFC;

    signal q_s  : std_logic_vector (NBit-1 downto 0):= (others => '0');
    signal crc_t    : std_logic_vector (NBit-1 downto 0):= (others => '0'); --registro temporaneo su cui fare le operazioni

    signal int_0    :std_logic := '0';
    signal int_2    :std_logic := '0';
    signal int_4    :std_logic := '0';
    signal int_8    :std_logic := '0';




    begin 
        int_0<= din xor q_s(7);
        int_2<= q_s(1) xor q_s(7);
        int_4<= q_s(3) xor q_s(7);

        GEN: for i in 0 to Nbit-1 generate

            FIRST:  if i=0 generate
                    FF1: DFC port map (
                            clk     => clk,
                            reset   => reset,
                            d   => int_0,
                            crc => crc_t(i), --funziona benissimo se metto dout(i)
                            q   => q_s(i)
                            );

                end generate FIRST; 

            THIRD: if i=2 generate
                    FF2: DFC port map (
                            clk     => clk,
                            reset   => reset,
                            d   => int_2,
                            crc => crc_t(i),
                            q   => q_s(i)
                                );
                end generate THIRD;

            FIFTH: if i=4 generate
                    FF4: DFC port map (
                            clk     => clk,
                            reset   => reset,
                            d   => int_4,
                            crc => crc_t(i),
                            q   => q_s(i)
                                );
                end generate FIFTH;


            INTERNAL: if i>0 and i<Nbit-1 and i/= 2 and i/=4 generate
                    FFI: DFC port map (
                            clk     => clk,
                            reset   => reset,
                            d   => q_s(i-1),
                            crc => crc_t(i),
                            q   => q_s(i)
                                );
                end generate INTERNAL;

            LAST:    if i=Nbit-1 generate
                    FFN: DFC port map (
                            clk     => clk,
                            reset   => reset,
                            d   => q_s(i-1),
                            crc => crc_t(i),
                            q   => q_s(i)
                            );
                end generate LAST;
    end generate GEN;


    variable t : natural := 0;

    begin
        if(rising_edge(clk)) then
            t:= t+1;
            if t=24 then 
                dout <= crc_t;
            end if;
        end if;
    end process;

end rtl;

Of course on line 35, where I put "d => din xor q_s(Nbit-1)", the compiler gives me an error. How can I obtain the result I want to get?

I tried putting intermediary signal to pass this problem, but I can't understand why this is not working as expected.

This is the code of the DFC component:


library IEEE;
use IEEE.std_logic_1164.all;

entity DFC is 
    port(
        clk :in std_logic;
        reset   :in std_logic;
        d   :in std_logic;
        crc :out    std_logic;
        q   :out    std_logic
    );  
end DFC;

architecture rtl of DFC is
    begin
        process(clk, reset, d)
        begin
            if(reset = '1')then
                q <= '0';
                crc<= '0';
            elsif (clk'event and clk='1') then
                q <= d;
                crc <= d;
            end if;
        end process;
end rtl;

Thanks all for the aswers. Gabriele.

Edit: I added all the LFSR code and the DFC code.


Solution

  • Your question is incomplete because it does not have a minimal reproductible code. In other word, it is hard to help you.

    Prior to VHDL-2008: You cannot perform such action : d => din xor q_s(Nbit-1) because this line is seen as an operation and that is not possible in an instantiation of an entity or a component.

    (like in this post for example: https://electronics.stackexchange.com/questions/184893/warning-actual-for-formal-port-a-is-neither-a-static-name-nor-a-globally-stati)

    However, there is a way to work around that, you have to create a new signal

    Notice that when you use your code, the error should be something like: Actual for formal port a is neither a static name nor a globally static expression

    With VHDL-2008:

    If look in the norm: http://www.fis.agh.edu.pl/~skoczen/hdl/ieee_std/ieee1076-2008.pdf You can find on paragraph 6.5.6.3 Port clauses:

    If a formal port of mode in is associated with an expression that is not globally static (see 9.4.1) and the formal is of an unconstrained or partially constrained composite type requiring determination of index ranges from the actual according to the rules of 5.3.2.2, then the expression shall be one of the following:

    • The name of an object whose subtype is globally static

    • An indexed name whose prefix is one of the members of this list

    • A slice name whose prefix is one of the members of this list and whose discrete range is a globally static discrete range

    • An aggregate, provided all choices are locally static and all expressions in element associations are expressions described in this list

    • A function call whose return type mark denotes a globally static subtype

    • A qualified expression or type conversion whose type mark denotes a globally static subtype

    • An expression described in this list and enclosed in parentheses

    In other word, in VHDL-2008, the code you provided should work.

    About your initialization problem, it is unclear, what signals/varibles are not initialized ? The best you can do is, if your first question is well answered by this post, then accept it has a solution or edit your question for more clarity. Then ask an other question in an other thread about the initialization problem. You can also post your question on Electronics Stackexchange