operation of std_logic:='X' - vhdl

The summarized question is at the bottom.
I'm analyzing and studying the existing VHDL code.
In this code, port reset_i was initialized to 'X' as you can see in below code.
entity ADC_fsm is
Port ( clk_i : in std_logic := 'X';
reset_i : in std_logic := 'X';
di_req_i : in std_logic := 'X';
wr_ack_i : in std_logic := 'X';
spi_ssel_i : in std_logic := 'X';
reg_enable_i : in std_logic := 'X';
reg_data_i : in std_logic_vector(23 downto 0);
adc_data_i : in std_logic_vector(11 downto 0);
bitslip_o : out std_logic;
sync_done_o : out std_logic;
wr_en_o : out std_logic;
spi_data_o : out std_logic_vector(23 downto 0) := (others => '0')
);
end ADC_fsm;
This port (reset_i) was not connected with other external port or signal.
And in next code,
begin
process(clk_i, reset_i)
begin
if (reset_i = '1') then
wr_en_o <= '0';
sync_done_o <= '0';
bitslip_o <= '0';
spi_data_o <= (others => '0');
s_delay_count <= 0;
s_write_indicator <= 0;
state <= ready;
elsif rising_edge(clk_i) then
wr_en_o <= '0';
sync_done_o <= '0';
bitslip_o <= '0';
I know that 'X' is neither 1 nor 0.
so, first if statement in above code won't work.
My question is how about elsif.
'X' is not '1', so 'X' included in elsif situation?
In short.
if (reset_i ='1') then
(A)
elsif(rising_edge(clk_i)) then
(B)
end if;
Does code (B) work only when reset_i = '0'?
or also work when reset_i ='X'?
THANKs

The type std_logic is an enumeration type with 9 values and has the following 9 values:
'U','X','0','1','Z','W','L','H','-'
Each value is just a distinct, arbitrary symbol. So, the line
if reset_i ='1' then -- the brackets are not required
will be true if and only if reset_i equals '1'. That's it. 'X' is just a different, arbitrary symbol.

Related

I2Cmaster with MPU6050 in VHDL not working

For my hobby project I try to make a quadcopter which balances itself with the MPU-6050. The flight controller shall be the FPGA Altera cyclone IV, because its fun. I'm coding it in VHDL.
Anyway I'm stuck on the I2C communication with the MPU-6050. As bases I used the I2C master VHDL code from: https://www.digikey.com/eewiki/pages/viewpage.action?pageId=10125324.
I try to read the gyro registers and print them out on 8 leds just to see if I have some communication coming in.
I have tried to run with a 1Hz prescaler all the I2C phases in the state machine and light up some leds just to see if all phases are run through. This is the case. I have assigned the pins 2.5V default, I use 10k pull up resistors. The MPU6050 works perferct on an arduino.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mpu6050_2 is
port( clk_50 : in std_logic;
areset : in std_logic;
i2c_SDA : INOUT STD_LOGIC;
i2c_SCL : INOUT STD_LOGIC;
leds : out std_LOGIC_VECTOR(7 downto 0)
);
end entity mpu6050_2;
architecture struc of mpu6050_2 is
component i2c_master is
GENERIC(
input_clk : INTEGER := 50_000_000;
bus_clk : INTEGER := 400_000);
PORT(
clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
ena : IN STD_LOGIC;
addr : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
rw : IN STD_LOGIC;
data_wr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
busy : OUT STD_LOGIC;
data_rd : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
ack_error : BUFFER STD_LOGIC;
sda : INOUT STD_LOGIC;
scl : INOUT STD_LOGIC);
end component ;
type machine is (config1, config2, gyroH, gyroL);
signal state : machine:= config1; --current state
signal SDA_int : std_LOGIC;
signal SCL_int : std_LOGIC;
signal i2c_ena : std_LOGIC;
signal i2c_busy : std_LOGIC;
signal busy_prev : std_LOGIC;
signal i2c_rw : std_LOGIC;
signal i2c_data_wr : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal gyro_data : std_LOGIC_VECTOR(15 downto 0);
signal i2c_data_rd : std_LOGIC_VECTOR (7 downto 0);
signal i2c_addr : STD_LOGIC_VECTOR(6 DOWNTO 0);
begin
process(areset, clk_50)
VARIABLE busy_cnt : INTEGER := 0; --keeps track of i2c busy signals during transaction
begin
if areset = '0' then
busy_cnt := 0;
i2c_ena <= '0';
state <= config1;
elsif rising_edge(clk_50) then
case state is
when config1 =>
busy_prev <= i2c_busy;
if (busy_prev = '0' and i2c_busy = '1') then
busy_cnt := busy_cnt + 1;
end if;
case busy_cnt is
when 0 =>
i2c_ena <= '1';
i2c_addr <= "1101000"; --MPU6050 adress
i2c_rw <= '0'; --write
i2c_data_wr <= x"6B"; -- hex6B powermanagement
when 1 =>
i2c_rw <= '0'; --write
i2c_data_wr <= "00000000"; -- ON with internal clock
when 2 =>
i2c_ena <= '0';
if(i2c_busy = '0') then
busy_cnt := 0;
state <= config2;
end if;
when others => NULL;
end case;
when config2 =>
busy_prev <= i2c_busy;
if (busy_prev = '0' and i2c_busy = '1') then
busy_cnt := busy_cnt + 1;
end if;
case busy_cnt is
when 0 =>
i2c_ena <= '1';
i2c_addr <= "1101000"; --MPU6050 adress
i2c_rw <= '0'; --write
i2c_data_wr <= x"1B"; -- Gyro config
when 1 =>
i2c_rw <= '0'; --write
i2c_data_wr <= "00000000"; -- 250 degree/sec, no self test
when 2 =>
i2c_ena <= '0';
if(i2c_busy = '0') then
busy_cnt := 0;
state <= gyroH;
end if;
when others => NULL;
end case;
when gyroH =>
busy_prev <= i2c_busy;
if (busy_prev = '0' and i2c_busy = '1') then
busy_cnt := busy_cnt + 1;
end if;
case busy_cnt is
when 0 =>
i2c_ena <= '1';
i2c_addr <= "1101000"; --MPU6050 adress
i2c_rw <= '0'; --write
i2c_data_wr <= x"43"; -- hex43 GYRO_OUT[15:8]
when 1 =>
i2c_rw <= '1'; --read
when 2 =>
i2c_ena <= '0';
if(i2c_busy = '0') then
gyro_data(15 downto 8) <= i2c_data_rd;
busy_cnt := 0;
state <= gyroL;
end if;
when others => NULL;
end case;
when gyroL =>
busy_prev <= i2c_busy;
if (busy_prev = '0' and i2c_busy = '1') then
busy_cnt := busy_cnt + 1;
end if;
case busy_cnt is
when 0 =>
i2c_ena <= '1';
i2c_addr <= "1101000"; --MPU6050 adress
i2c_rw <= '0'; --write
i2c_data_wr <= x"44"; -- hex44 GYRO_OUT[7:0]
when 1 =>
i2c_rw <= '1'; --read
when 2 =>
i2c_ena <= '0';
if(i2c_busy = '0') then
gyro_data(7 downto 0) <= i2c_data_rd;
busy_cnt := 0;
state <= gyroH;
end if;
when others => NULL;
end case;
end case;
end if;
end process;
u0: i2c_master
port map(clk => clk_50, reset_n => areset, ena => i2c_ena, addr => i2c_addr, rw => i2c_rw, data_wr => i2c_data_wr, busy => i2c_busy, data_rd => i2c_data_rd
, sda => SDA_int, scl => SCL_int);
leds(7) <= gyro_data(0); --D4
leds(6) <= gyro_data(1); -- D5
leds(5) <= gyro_data(4); -- D6
leds(4) <= gyro_data(7); -- D7
leds(3) <= gyro_data(8); -- D8
leds(2) <= gyro_data(11); -- D9
leds(1) <= gyro_data(13); -- D10
leds(0) <= gyro_data(15); -- D11
i2c_SDA <= SDA_int;
i2c_SCL <= SCL_int;
end struc;
Result:
all the leds dont change status despite if i rotate the MPU6050. So no communication. Can anyone help me what i'm doing wrong?
First: I'm using the same component in one of my designs and do confirm it works.
I think you are just using the wrong i2c address to begin with.
In datasheets, i2c addresses are usually given including the read/write bit (for the MPU-6050, this is 0x68/01101000 and 0x69/01101001). The i2c master component used, however, expects to build the final i2c address by itself by appending (&) the i2c rw bit to the given address (see line 124 in the original sources), thus you must pass the address from the datasheet shifted by one bit.
Try using 0x34/0110100 as i2c address for read and write instead.
I only looked very briefly into the rest of your code (so there might be other culprits as well), but this should be enough to get you going.

VHDL Concurrent Array Assignment - Memory Structure gets wiped

I've been wrestling with a rather large project and I've come to an impasse, the following code simulates and works as expected except that it reassigns all memory addresses to UU upon a signal assignment. The code describe a fully descending stack with integrated stack pointer. I'm trying to avoid process statements for timing purposes and I would really like the memory block to remain a signal array (and not a variable array) for debugging purposes.
The selected address data must be present upon the rising clock edge (immediately) and must be completely stored and ready for re-reading no later than the falling edge of the same clock signal.
Maybe I've just been staring at my description for too long, but I don't understand why it's reassigning every value to UU when I write to a single address. There's definitely a VHDL rule I'm breaking here. I would like both an asynchronous reset to clear the entire array, as well as a synchronous read/write. If advisable, I would like to eventually remove the clock dependency altogether.
Here's the relevant code block:
-- Fully Descending Stack with integrated Stack Pointer --
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY STACK IS
GENERIC(
BIT_WIDTH : INTEGER := 10;
BIT_DEPTH : INTEGER := 5
);
PORT(
CLK : IN STD_LOGIC;
CE : IN STD_LOGIC;
RESET : IN STD_LOGIC;
LOAD : IN STD_LOGIC;
PUSH : IN STD_LOGIC;
POINTER_WRITE_ADDRESS : IN STD_LOGIC_VECTOR(BIT_DEPTH - 1 DOWNTO 0);
STACK_DATA_IN : IN std_logic_vector(BIT_WIDTH - 1 DOWNTO 0);
-- OUTPUT SIGNALS --
POINTER_ADDRESS : OUT STD_LOGIC_VECTOR(BIT_DEPTH - 1 DOWNTO 0) := (OTHERS => '0');
STACK_DATA_OUT : OUT std_logic_vector(BIT_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
STACK_FULL : OUT STD_LOGIC := '0';
STACK_EMPTY : OUT STD_LOGIC := '1'
);
END STACK;
ARCHITECTURE Behavioral OF STACK IS
CONSTANT STACK_DEPTH : INTEGER := (2**BIT_DEPTH) - 1;
SUBTYPE WORD_SIZE IS std_logic_vector(BIT_WIDTH - 1 DOWNTO 0);
TYPE MEMORY IS ARRAY (STACK_DEPTH DOWNTO 0) OF WORD_SIZE;
SIGNAL STACK_MEMORY : MEMORY := (OTHERS => (OTHERS => '0'));
SIGNAL STACK_POINTER : INTEGER := STACK_DEPTH;
BEGIN
STACK_MEMORY <= (OTHERS => (OTHERS => '0')) WHEN RESET = '1' ELSE
(to_integer(unsigned(POINTER_WRITE_ADDRESS)) => STACK_DATA_IN) WHEN LOAD = '1' AND rising_edge(CLK) ELSE
( STACK_POINTER => STACK_DATA_IN) WHEN (PUSH = '1' AND CE = '1' AND NOT (STACK_POINTER = 0)) AND rising_edge(CLK);
STACK_POINTER <= (STACK_POINTER + 1) WHEN PUSH = '0' AND CE = '1'AND NOT(STACK_POINTER = STACK_DEPTH) AND rising_edge(CLK)ELSE
(STACK_POINTER - 1) WHEN PUSH='1' AND CE = '1' AND NOT (STACK_POINTER = 0) AND rising_edge(CLK);
STACK_EMPTY <= '1' WHEN STACK_POINTER = STACK_DEPTH else '0';
STACK_FULL <= '1' WHEN STACK_POINTER = 0 else '0';
STACK_DATA_OUT <= STACK_MEMORY(STACK_POINTER+1) WHEN CE = '1' AND PUSH='0' AND (NOT(STACK_POINTER = STACK_DEPTH)) ELSE
STACK_DATA_IN WHEN LOAD='1' or (CE = '1' AND PUSH='1' AND
NOT(STACK_POINTER = 0))ELSE
(OTHERS => '0') WHEN (STACK_POINTER = STACK_DEPTH);
POINTER_ADDRESS <= std_logic_vector(to_unsigned(STACK_POINTER,
POINTER_ADDRESS'length));
END Behavioral;
------------------------------EDIT--------------------------------
Okay, I've taken a look at some reference material and rewritten my code as follows:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY STACK IS
GENERIC(
-- DATA STORAGE GENERICS --
BIT_WIDTH : INTEGER := 10;
BIT_DEPTH : INTEGER := 8
);
PORT(
-- NON-SPECIFIC INPUT SIGNALS --
CLK : IN STD_LOGIC;
CE : IN STD_LOGIC;
RESET : IN STD_LOGIC;
-- STACK OPERATION INPUT SIGNALS --
LOAD : IN STD_LOGIC;
PUSH : IN STD_LOGIC;
POINTER_WRITE_ADDRESS : IN STD_LOGIC_VECTOR(BIT_DEPTH - 1 DOWNTO 0);
STACK_DATA_IN : IN std_logic_vector(BIT_WIDTH - 1 DOWNTO 0);
-- OUTPUT SIGNALS --
POINTER_ADDRESS : OUT STD_LOGIC_VECTOR(BIT_DEPTH - 1 DOWNTO 0) := (OTHERS => '0');
STACK_DATA_OUT : OUT std_logic_vector(BIT_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
STACK_FULL : OUT STD_LOGIC := '0';
STACK_EMPTY : OUT STD_LOGIC := '1'
);
END STACK;
ARCHITECTURE Behavioral OF STACK IS
CONSTANT STACK_TOP : INTEGER := (2**BIT_DEPTH) - 1;
SUBTYPE WORD_SIZE IS STD_LOGIC_VECTOR(BIT_WIDTH - 1 DOWNTO 0);
TYPE MEMORY IS ARRAY (STACK_TOP DOWNTO 0) OF WORD_SIZE;
SIGNAL STACK_MEMORY : MEMORY := (OTHERS => (OTHERS => '0'));
SIGNAL STACK_POINTER : INTEGER := STACK_TOP;
SIGNAL STACK_POINTER_INPUT : INTEGER := 0;
BEGIN
STACK_POINTER_INPUT <= to_integer(unsigned(POINTER_WRITE_ADDRESS));
POINTER_ADDRESS <= std_logic_vector(to_unsigned(STACK_POINTER, POINTER_ADDRESS'length));
STACK_POINTER_CONTROL : PROCESS(CLK)
BEGIN
IF (Rising_Edge(CLK)) THEN
IF (RESET = '1') THEN
STACK_POINTER <= STACK_TOP;
ELSIF (LOAD = '1') THEN
STACK_POINTER <= STACK_POINTER_INPUT;
ELSIF (CE = '1' AND PUSH = '0' AND STACK_POINTER < STACK_TOP) THEN
STACK_POINTER <= STACK_POINTER + 1;
ELSIF (CE = '1' AND PUSH = '1' AND STACK_POINTER > 0) THEN
STACK_POINTER <= STACK_POINTER - 1;
END IF;
END IF;
END PROCESS STACK_POINTER_CONTROL;
BLOCK_MEMORY_CONTROL : PROCESS(CLK)
BEGIN
IF (Rising_Edge(CLK)) THEN
IF (RESET = '1') THEN
STACK_MEMORY <= (OTHERS => (OTHERS => '0'));
-- POP | Erase data from popped address --
ELSIF (CE = '1' AND PUSH = '0') THEN
STACK_MEMORY(STACK_POINTER) <= (OTHERS => '0');
-- PUSH | Write data to stack pointer --
ELSIF (CE = '1' AND PUSH = '1') THEN
STACK_MEMORY(STACK_POINTER) <= STACK_DATA_IN;
END IF;
END IF;
END PROCESS BLOCK_MEMORY_CONTROL;
STACK_DATA_OUT <= (OTHERS => '0') WHEN RESET = '1'
ELSE STACK_DATA_IN WHEN STACK_POINTER = 255
ELSE STACK_MEMORY(STACK_POINTER + 1);
STACK_EMPTY <= '1' WHEN STACK_POINTER = STACK_TOP else '0';
STACK_FULL <= '1' WHEN STACK_POINTER = 0 else '0';
END Behavioral;
It now seems to operate correctly in all simulation tests, but I'm worried about timing conflicts between states. Is there a better way to improve upon this design?

Simple VHDL ALU will not show inputs or overflow in the waveform

I'm supposed to write up a 16-bit ALU. My professor wants us to try and code the adder and sub of the ALU with a
signal tmp : std_logic_vector(16 downto 0); and then in the case for the select input s we put:
tmp <= conv_std_logic_vector(conv_integer(a) + conv_integer(b), 17);
After experimenting with it for a while, my waveform only showed the inputs' values as UUUUUUUUUUUUUUUU. Even after I had commented out the conv_std_logic_vector(...) stuff.
Is there a simple explanation as to why my inputs aren't showing up in the waveform?
Here is my code:
-- 16-Bit ALU
-- By: Logan Jordon
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
--use ieee.std_logic_arith.all;
 
entity alu16 is
port (
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s : in std_logic_vector(1 downto 0);
r : out std_logic_vector(15 downto 0);
cout : out std_logic;
lt, eq, gt : out std_logic;
overflow : out std_logic
);
end entity alu16;
architecture beh of alu16 is
signal tmp : std_logic_vector(16 downto 0);
signal add_overflow : std_logic;
signal sub_overflow : std_logic;
begin
-- PROCESS
process(a, b, add_overflow, sub_overflow)
begin
case s is
--ADD
when "00" =>
--tmp <= conv_std_logic_vector(conv_integer(a) + conv_integer(b), 17);
tmp <= a + b;
overflow <= add_overflow;
--SUB
when "01" =>
--tmp <= conv_std_logic_vector(conv_integer(a) - conv_integer(b), 17);
tmp <= a - b;
overflow <= sub_overflow;
--AND
when "10" =>
tmp <= '0' & a AND b;
overflow <= '0';
--OR
when "11" =>
tmp <= '0' & a OR b;
overflow <= '0';
when others =>
tmp <= "00000000000000000";
end case;
--One-Bitters
if a > b then
gt <= '1';
lt <= '0';
eq <= '0';
elsif a < b then
lt <= '1';
gt <= '0';
eq <= '0';
elsif a = b then
eq <= '1';
lt <= '0';
gt <= '0';
end if;
end process;
--OUTPUTS
cout <= tmp(16);
r <= tmp(15 downto 0);
add_overflow <= '1' when (a(15) = b(15)) and (a(15) /= tmp(15))
else '0';
sub_overflow <= '1' when (a(15) = NOT b(15)) and (a(15) /= tmp(15))
else '0';
end beh;
EDIT: In the case that it might be my test bench, here's the code for my testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
entity alu16_tb is
end alu16_tb;
architecture behavior of alu16_tb is
component ALU16
port(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s : in std_logic_vector(1 downto 0);
r : out std_logic_vector(15 downto 0);
cout : out std_logic;
lt, eq, gt : out std_logic;
overflow : out std_logic
);
end component;
-- Signals to interface with the UUT
-- Set each of the input vectors to unique values to avoid
-- needing a process to drive them below
signal a : std_logic_vector(15 downto 0) := "0000000000000000";
signal b : std_logic_vector(15 downto 0) := "0000000000000000";
signal s : std_logic_vector(1 downto 0) := "00";
signal r : std_logic_vector(15 downto 0):= "0000000000000000";
signal cout : std_logic := '0';
signal lt : std_logic := '0';
signal gt : std_logic := '0';
signal eq : std_logic := '0';
signal overflow : std_logic := '0';
constant tick : time := 10 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut : ALU16 port map (
a => a,
b => b,
s => s,
r => r,
cout => cout,
lt => lt,
gt => gt,
eq => eq,
overflow => overflow
);
-- Drive selector bits
drive_s : process
begin
a <= "0000000000000001";
b <= "0000000000000010";
wait for (tick*2);
s <= "00";
wait for (tick*2);
s <= "01";
wait for (tick*2);
s <= "10";
wait for (tick*2);
s <= "11";
end process drive_s;
end;

Multiple read of register in VHDL and encapsulation leads to wrong value

I currently confront one problem with reading two registers and send their value via proxy to tile on FPGA. There are three input channels for encoded signals which consis of pulses with frequency of 50khz, then the signal were sampled by a local 100Mhz clock on FPGA board. In the module two channels were counted for their pulses and I use bit shift for encapsulation to put the read value from two counter into one 32bits std_bit_vector to send via proxy.
If I only transfer counting value of one channel and sent them via proxy signals, it behaviors always correctly. However when reading two counting value from two register and doing the encapsulation, the 16 higher bits of the shifted value is always increasing faster than it supposed to be. In another word, counting process ifself is correct while there is also no problems with communication between counting module and tile.
I dont know the problem is caused by the process reading too fast from two registers and leads to synchronization problem. One channel input signal only increases by one per 500 counts, while another counting 500 per rotation.One rotation is controlled by hand on the encoder (THen u can imagine the low frequency of the input signals)
THen encapsulation were put in last two lines of the module.
THanks in advance.
THe module of counting is design as following:
library rdt_dtl_proxy_targetlib;
use rdt_dtl_proxy_targetlib.rdt_dtl_proxy_target_cmp_pkg.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_ARITH.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity dtl_pmod_rotary is
generic (
WIDTH_DTL_CMD_ADDR : natural:= 32;
WIDTH_DTL_CMD_BLOCK_SIZE : natural:= 5;
WIDTH_DTL_DATA : natural:= 32;
WIDTH_DTL_WR_MASK : natural:= 4
);
port (
clk : in std_logic;
rst_n : in std_logic;
rotary_a : in std_logic;
rotary_b : in std_logic;
rotary_i : in std_logic;
dtl_cmd_valid_t_proxy0 : in std_logic;
dtl_cmd_accept_t_proxy0 : out std_logic;
dtl_cmd_addr_t_proxy0 : in std_logic_vector(WIDTH_DTL_CMD_ADDR - 1 downto 0);
dtl_cmd_read_t_proxy0 : in std_logic;
dtl_cmd_block_size_t_proxy0 : in std_logic_vector(WIDTH_DTL_CMD_BLOCK_SIZE - 1 downto 0);
dtl_wr_valid_t_proxy0 : in std_logic;
dtl_wr_last_t_proxy0 : in std_logic;
dtl_wr_accept_t_proxy0 : out std_logic;
dtl_wr_data_t_proxy0 : in std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
dtl_wr_mask_t_proxy0 : in std_logic_vector(WIDTH_DTL_WR_MASK - 1 downto 0);
dtl_rd_last_t_proxy0 : out std_logic;
dtl_rd_valid_t_proxy0 : out std_logic;
dtl_rd_accept_t_proxy0 : in std_logic;
dtl_rd_data_t_proxy0 : out std_logic_vector(WIDTH_DTL_DATA - 1 downto 0)
);
end dtl_pmod_rotary;
architecture rtl of dtl_pmod_rotary is
signal dtl_rd_data_15 : std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
signal dtl_rd_accept_14 : std_logic;
signal dtl_cmd_block_size_6 : std_logic_vector(WIDTH_DTL_CMD_BLOCK_SIZE - 1 downto 0);
signal dtl_wr_data_10 : std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
signal dtl_cmd_read_5 : std_logic;
signal dtl_rd_last_12 : std_logic;
signal dtl_rst_n_1 : std_logic;
signal dtl_wr_valid_7 : std_logic;
signal dtl_wr_accept_9 : std_logic;
signal dtl_wr_last_8 : std_logic;
signal dtl_cmd_addr_4 : std_logic_vector(WIDTH_DTL_CMD_ADDR - 1 downto 0);
signal dtl_cmd_valid_2 : std_logic;
signal dtl_clk_0 : std_logic;
signal dtl_rd_valid_13 : std_logic;
signal dtl_wr_mask_11 : std_logic_vector(WIDTH_DTL_WR_MASK - 1 downto 0);
signal dtl_cmd_accept_3 : std_logic;
-- signals for counting
signal cnt_r : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_r_a : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_r_b : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_r_i : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_nxt_a : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_nxt_b : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_nxt_i : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_ref_i : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal rotary_a_r : std_logic; --register storing data from rotary_a.
signal rotary_a_2r : std_logic; --register storing data from rotary_a_r
signal rotary_b_r : std_logic; --register storing data from rotary_b.
signal rotary_b_2r : std_logic; --register storing data from rotary_b_r
signal rotary_i_r : std_logic; --register storing data from rotary_i.
signal rotary_i_2r : std_logic; --register storing data from rotary_i_r
begin
dtl_clk_0 <= clk;
dtl_rst_n_1 <= rst_n;
dtl_cmd_valid_2 <= dtl_cmd_valid_t_proxy0;
dtl_cmd_accept_t_proxy0 <= dtl_cmd_accept_3;
dtl_cmd_addr_4 <= dtl_cmd_addr_t_proxy0;
dtl_cmd_read_5 <= dtl_cmd_read_t_proxy0;
dtl_cmd_block_size_6 <= dtl_cmd_block_size_t_proxy0;
dtl_wr_valid_7 <= dtl_wr_valid_t_proxy0;
dtl_wr_last_8 <= dtl_wr_last_t_proxy0;
dtl_wr_accept_t_proxy0 <= dtl_wr_accept_9;
dtl_wr_data_10 <= dtl_wr_data_t_proxy0;
dtl_wr_mask_11 <= dtl_wr_mask_t_proxy0;
dtl_rd_last_t_proxy0 <= dtl_rd_last_12;
dtl_rd_valid_t_proxy0 <= dtl_rd_valid_13;
dtl_rd_accept_14 <= dtl_rd_accept_t_proxy0;
dtl_rd_data_t_proxy0 <= dtl_rd_data_15;
-- Begin child instances
proxy0 : rdt_dtl_proxy_target
generic map (
DTL_DATA_WIDTH => WIDTH_DTL_DATA,
DTL_ADDR_WIDTH => WIDTH_DTL_CMD_ADDR,
DTL_BLK_SIZE_WIDTH => WIDTH_DTL_CMD_BLOCK_SIZE,
DTL_WR_MASK_WIDTH => WIDTH_DTL_WR_MASK
)
port map (
dtl_clk => dtl_clk_0,
dtl_rst_n => dtl_rst_n_1,
dtl_cmd_accept_t => dtl_cmd_accept_3,
dtl_cmd_addr_t => dtl_cmd_addr_4,
dtl_cmd_block_size_t => dtl_cmd_block_size_6,
dtl_cmd_read_t => dtl_cmd_read_5,
dtl_cmd_valid_t => dtl_cmd_valid_2,
dtl_rd_accept_t => dtl_rd_accept_14,
dtl_rd_data_t => dtl_rd_data_15,
dtl_rd_last_t => dtl_rd_last_12,
dtl_rd_valid_t => dtl_rd_valid_13,
dtl_wr_accept_t => dtl_wr_accept_9,
dtl_wr_data_t => dtl_wr_data_10,
dtl_wr_last_t => dtl_wr_last_8,
dtl_wr_mask_t => dtl_wr_mask_11,
dtl_wr_valid_t => dtl_wr_valid_7,
cmd_accept => '1', --target accept handshake,input port of Proxy
cmd_addr => open,
cmd_block_size => open,
cmd_read => open, --output port of Proxy
cmd_valid => open, --output port of Proxy
rd_accept => open, --output port of Proxy, return the accept info from initializer
--rd_data => x"00000003", --test value
rd_data => cnt_r, --input port of proxy, for sending the counter value
rd_last => '1',
rd_valid => '1',
wr_accept => '0', --return value to Proxy indicating prepared for receiving written data from initiator
wr_data => open, --receive data from Proxy that written by initializer
wr_last => open,
wr_mask => open,
wr_valid => open
);
-- Counting pulses
-- combinatorial process
comb_counter_process_a : process(rotary_a_r, rotary_a_2r)
begin
if rotary_a_r = '1' and rotary_a_2r = '0' then
cnt_nxt_a <= cnt_r_a + 1;
else
cnt_nxt_a <= cnt_r_a;
end if;
end process;
-- sequential process with synchronous reset
seq_counter_process_a : process(clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
cnt_r_a <= (others => '0');
rotary_a_r <= '0';
rotary_a_2r <= '0';
else
-- registering
cnt_r_a <= cnt_nxt_a ;
rotary_a_2r <= rotary_a_r;
rotary_a_r <= rotary_a;
--cnt_r <= cnt_r_a(8 downto 0);
end if;
end if;
end process;
comb_counter_process_b : process(rotary_b_r, rotary_b_2r)
begin
if rotary_b_r = '1' and rotary_b_2r = '0' then
cnt_nxt_b <= cnt_r_b + 1;
else
cnt_nxt_b <= cnt_r_b;
end if;
end process;
-- sequential process with synchronous reset
seq_counter_process_b : process(clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
cnt_r_b <= (others => '0');
rotary_b_r <= '0';
rotary_b_2r <= '0';
else
-- registering
cnt_r_b <= cnt_nxt_b;
rotary_b_2r <= rotary_b_r;
rotary_b_r <= rotary_b;
--cnt_r(31 downto 16) <= X"ABCD";
end if;
end if;
end process;
comb_counter_process_i : process(rotary_i_r, rotary_i_2r)
begin
if rotary_i_r = '1' and rotary_i_2r = '0' then
cnt_nxt_i <= cnt_r_i + 1;
else
cnt_nxt_i <= cnt_r_i;
end if;
end process;
-- sequential process with synchronous reset
seq_counter_process_i : process(clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
cnt_r_i <= (others => '0');
rotary_i_r <= '0';
rotary_i_2r <= '0';
else
-- registering
cnt_r_i <= cnt_nxt_i;
rotary_i_2r <= rotary_i_r;
rotary_i_r <= rotary_i;
--cnt_r(15 downto 0) <= X"1234"; --the digits for cnt_r_i may change
end if;
end if;
end process;
cnt_r(31 downto 16) <= cnt_r_b(15 downto 0);
cnt_r(15 downto 0) <= cnt_r_i(15 downto 0);
end rtl;

VHDL 2008 and CASE statement

I've a question about a case statement and VHDL 2008. I've an entity defined in this way :
entity multiplier_v2 is
generic( WIDTH_WORD : integer := 32;
WIDTH_RSA : integer := 2048;
LENGTH_ADDRESS : integer := 6 );
port (
reset : in std_logic;
clk : in std_logic;
start : in std_logic;
input_1 : in std_logic_vector(WIDTH_WORD - 1 downto 0);
input_2 : in std_logic_vector(WIDTH_WORD - 1 downto 0);
module : in std_logic_vector(WIDTH_WORD - 1 downto 0);
output : out std_logic_vector(WIDTH_WORD - 1 downto 0);
ack_data : out std_logic;
data_valid : out std_logic;
new_module : in std_logic;
Inside the module I've a signal declared in this way :
signal counter_ack : std_logic_vector(LENGTH_ADDRESS - 1 downto 0);
I use this signal in a case statement :
case counter_ack is
when (others => '1') =>
ack_data <= '0';
when others =>
counter_ack <= counter_ack + 1;
end case;
Now, I'm pretty sure that VHDL-2008 option is enabled in my synthesis tool but I have the following error regarding that part of my code:
2049990 ERROR - E:/My_Designs/Custom Module/Montgomery_Multiplier/Diamond/src/multiplier_v2.vhd(456,6-461,15) (VHDL-1544) array type case expression must be of a locally static subtype
I've read that this error should be fixed in VHDL-2008. Any ideas ?
I compiled the code displayed below in Quartus II with VHDL 2008 compiler option. I got no error. Does your case statement is in a process?
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;
ENTITY casestate IS
generic( WIDTH_WORD : integer := 32;
WIDTH_RSA : integer := 2048;
LENGTH_ADDRESS : integer := 6 );
port (
reset : in std_logic;
clk : in std_logic;
ack_data : out std_logic
);
END casestate;
ARCHITECTURE fpga OF casestate IS
signal counter_ack : std_logic_vector(LENGTH_ADDRESS - 1 downto 0);
BEGIN
process(clk,reset)
begin
if(reset = '0')then
ack_data <= '0';
elsif(rising_edge(clk))then
case counter_ack is
when (others => '1') =>
ack_data <= '0';
when others =>
counter_ack <= counter_ack + 1;
ack_data <= '1';
end case;
end if;
end process;
end fpga;
You need to specify the range, (others => '1') is an unconstrained vector
So you could do something like
when (counter_ack'range => '1') =>
which is a vector of defined length that should work in more software that doesn't make inferences.
this also works for if statements
if VEC = (VEC'range => '0') then
CODE
end if;

Resources