Showing posts with label VHDL. Show all posts
Showing posts with label VHDL. Show all posts

Oct 14, 2018

Simple and efficient FPGA reset method (reset for records)

I hope you are using VHDL records extensively. They are not as powerful as SystemVerilog data types and interfaces, but it's a huge step forward from individual bits and bit arrays of Verilog. I don't understand why some people use VHDL and don't use this feature of VHDL! Records make your code significantly clearer and crisper. They reduce risk of forgetting to assign a value to a signal of a complex data bus and make your description 10 times shorter while improving readability.

Jun 14, 2018

Features of for... loop in VHDL


If you didn't noticed, in my previous post I used "for" like "foreach" across enumerate type


1
2
3
type LaneIndex is (L0,L1,L2,L3);
...
for Lane in LaneIndex loop

In fact, you also can use it like that

for i in Arr'range loop
if Arr is an array.

Or you can use it like that:


1
2
3
subtype LanesRange is integer range 0 to LanesInCore-1;
...
for Lane in LanesRange loop
Highly recommend!

Jun 13, 2018

Special index types of VHDL arrays


Actually, in VHDL your array don't have to have integer indexes.

1
2
type ByteIndex is (B0,B1,B2,B3);
type LaneType is array (ByteIndex) of std_logic_vector(7 downto 0);

I used this fact when I had to use multidimensional arrays to prevent mistakes when you mix up dimensions of your arrays.
For example, let's suppose you have a bus, consisting of 4 lanes and each of the lanes contains 4 bytes.


1
2
3
4
5
6
7
8
type LaneType is array (0 to 3) of std_logic_vector(7 downto 0);
type LaneBusType is array(0 to 3) of LaneType;
 .....
            for Lane in 0 to 3 loop
                L(Lane)(0)(i) <= not L(Lane)(0)(i); --OK
               -- L(0)(Lane)(i) <= not L(0)(Lane)(i);
               -- error, but absolutely legal
            end loop;

In contrast, if you use non-integer indexes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   type LaneIndex is (L0,L1,L2,L3);
    type ByteIndex is (B0,B1,B2,B3);

    type LaneType is array(ByteIndex) of std_logic_vector(7 downto 0);
    type LaneBusType is array(LaneIndex) of LaneType;
 
    signal clk : std_logic;
    signal L : LaneBusType := (others => (others => (others => '0')));
begin

    process is
    begin
        clk <= '0';
        wait for 5 ns;
        clk <= '1';
        wait for 5 ns;
    end process;
    
    process(clk) is
    variable i : natural := 0;
    begin
        if rising_edge(clk) then
            for Lane in LaneIndex loop
                L(Lane)(B0)(i) <= not L(Lane)(B0)(i); --OK
               -- L(B0)(Lane)(i) <= not L(B0)(Lane)(i);
               -- type error near b0 ; current type byteindex; 
               -- expected type laneindex
            end loop;
            i := (i+1) mod 8;
        end if;
    end process;

The method helps you to avoid mistakes by controlling types of indexes. On the other hand, it adds some hassle. It is up to you when to use it.