VHDL downto incorrect MSB - vhdl

I have the following input signal:
addr : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
As far as I know, this means that addr(9) is the most significant bit.
But when run a simulation and assign, say, 128 to it, I get the following:
0(9) 0(8) 0(7) 0(6) 0(5) 0(4) 0(3) 1(2) 0(1) 0(0)
Meaning that the most significant bit is actually addr(0).
The assignment is done through simulation via vector waveform, in Quartus 9.1. I assign an arbitrary value to it.
Here is part of the .vhd file, where I use this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY ram_256x4B IS
PORT(clk, wr_en : IN STD_LOGIC; -- clock, write control signal
addr : IN STD_LOGIC_VECTOR(9 DOWNTO 0); -- read and write addresses
d : IN STD_LOGIC_VECTOR(31 DOWNTO 0); -- data to be written
q : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)); -- memory read output
END ram_256x4B;
ARCHITECTURE comportamental OF ram_256x4B IS
SIGNAL addr_validation_bits : STD_LOGIC;
BEGIN
addr_validation_bits <= addr(9) & addr(8);
END comportamental;
If the valued of addr is 2, I expect addr(9) and addr(8) to be both 0, but instead they are 0 and 1, respectively.

This assigns a STD_LOGIC_VECTOR with 128.
architecture ...
signal addr : STD_LOGIC_VECTOR(9 downto 0);
begin
addr <= std_logic_vector(to_unsigned(128, addr'length));
end;
addr(7) is '1', all other bits are '0'.

Related

How to eliminate the logic gate and the adder

The logic gate in the RTL view was a latch previously. As an answer suggests, I assign each input with outputs. And the latch turns into a logic gate. I don't know whether it is a correct way to solve the problem. There is also an adder connected to the counter.
I want to eliminate the adder and the logic gate. (??? T^T).
What should I modify?
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use IEEE.std_logic_unsigned.all;
entity mux8x1 is port( input: in std_logic_vector( 7 downto 0); clk: in std_logic; --s: buffer std_logic; --rst : in std_logic; --d: buffer std_logic; q: out std_logic_vector (7 downto 0) --o: buffer std_logic_vector (3 downto 0) ); end mux8x1;
architecture mux of mux8x1 is signal count : std_logic_vector(3 downto 0);
--signal count_state: std_logic_vector (3 downto 0); signal serial: std_logic;
--shiftregister
signal internal: std_logic_vector (7 downto 0); signal d: std_logic;
begin --【The counter】 process(clk) --variable internal: std_logic_vector (7 downto 0); --variable d: std_logic; --variable initial: std_logic_vector (7 downto 0) :="01010101";
begin
if (clk'event and clk = '1') then
count <= count + 1;
end if;
end process;
--count_state <= count; --To divide the counter
--section1 for the counter --8x1 multiplxer combined with counter
process(count,input,clk) --variable serialin: std_logic; begin --serialin:='0'; if (count(3) <='0') then case count(2 downto 0) is --8 possible states for PToS
when "000"=> serial <=input(0);
when "001"=> serial <=input(1);
when "010"=> serial <=input(2);
when "011"=> serial <=input(3);
when "100"=> serial <=input(4);
when "101"=> serial <=input(5);
when "110"=> serial <=input(6);
when "111"=> serial <=input(7);
when others => serial <= '0'; end case; else serial <='0';
end if; --serial<=serialin; end process;
-- end if; end mux;
The following is the RTL viewer.
enter image description here
The reason that you get a latch, is because you do not apply a signal value to "serial" in any case when the process is started: Then "serial" keeps its old value which leads to a latch at synthesis, where this kept value is taken from.
So it is a good idea to assign a default value to any signal you assign values to in a process.
When you want to get a register (triggered by a clock edge) you must use a process which is only sensitive to a clock signal (and a reset signal) and uses as a condition "rising_edge(clk)". Of course you do not need a default assignment here.

VHDL Moving average: simulation & synthesis result differ (Vivado)

For my project I need to reduce a noise of an ADC output and implemented a simple moving average filter in VHDL.
Although it works in simulation (see the picture):
it has some strange behavior if I display it on the chipscope when the system is running in FPGA (see the picture):
The VHDL code I use for the moving average is as follows:
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
use ieee.numeric_std.all;
entity moving_avg is
generic(
SAMPLES_COUNT : integer := 32
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
sample_i : in std_logic_vector(11 downto 0);
avg_o : out std_logic_vector(11 downto 0)
);
end;
architecture rtl of moving_avg is
type sample_buff_t is array (1 to SAMPLES_COUNT) of std_logic_vector(11 downto 0);
signal sample_buffer : sample_buff_t;
signal sum : std_logic_vector(31 downto 0);
constant wid_shift : integer := integer(ceil(log2(real(SAMPLES_COUNT))));
signal avg_interm_s : std_logic_vector(31 downto 0);
begin
process (clk_i, rst_n_i) begin
if rst_n_i='1' then
sample_buffer <= (others => sample_i);
sum <= std_logic_vector(unsigned(resize(unsigned(sample_i), sum'length)) sll wid_shift) ;
elsif rising_edge(clk_i) then
sample_buffer <= sample_i & sample_buffer(1 to SAMPLES_COUNT-1);
sum <= std_logic_vector(unsigned(sum) + unsigned(sample_i) - unsigned(sample_buffer(SAMPLES_COUNT)));
end if;
end process;
avg_interm_s <= std_logic_vector((unsigned(sum) srl wid_shift));
avg_o <= avg_interm_s(11 downto 0);
end;
I use Xilinx Vivado tool 2015.2 running on Ubuntu 14.04 x64.
Could you please help me to identify the problem, such
that results in simulation correspond to results after synthesis?

16-bit bitwise and in VHDL?

If I needed to perform a bitwise AND operation of two 16bit inputs and obtain a 16bit output in VHDL, would I be able to just AND the two inputs and store the result as the output vector? Or would I need to loop through each bit of the inputs, AND them, then store the result in the output vector? Would this work similarly for operations like or and xor?
The "and" operator is overloaded in the std_logic_1164 package for std_logic, std_ulogic, std_logic_vector, and std_ulogic_vector (the types typically used). It is also defined for bit and bit_vector (as well as signed and unsigned).
So it is as straightforward as just applying the "and"operator. For example:
architecture rtl of test is
signal a : std_logic_vector(15 downto 0);
signal b : std_logic_vector(15 downto 0);
signal y : std_logic_vector(15 downto 0);
begin
y <= a and b; -- Or 'y <= a xor b;' or 'y <= a or b;', etc
end architecture rtl;
You can just use and.
library IEEE;
use IEEE.std_logic_1164.all;
entity and_gate is
port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
q: out std_logic_vector(15 downto 0));
end and_gate;
architecture rtl of and_gate is
begin
q <= a and b;
end rtl;
http://www.edaplayground.com/x/Xuw

error while using the resize function in vhdl

I am trying to program an FPU unit in VHDL. I am doing my first steps. I get two errors while executing this instruction:
mantissa1 <= std_logic_vector(resize(unsigned(mantissa1),mantissa1'length + d));
The errors are:
Error: C:/Modeltech_pe_edu_10.4a/examples/fpu/shifter.vhd(38): Illegal type conversion to ieee.std_logic_1164.STD_LOGIC_VECTOR (operand type is not known).
Error: C:/Modeltech_pe_edu_10.4a/examples/fpu/shifter.vhd(36): (vcom-1078) Identifier "unsigned" is not directly visible.
Here is my code
library ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_misc.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_arith.ALL;
use ieee.numeric_std.all;
entity fpu is
port (
E1,E2 : IN std_logic_vector( 30 downto 23);
M1,M2 : IN std_logic_vector( 22 downto 0);
S1,S2 : IN std_logic_vector (31 downto 31);
op : IN std_logic_vector (1 downto 0);
SUM : OUT std_logic_vector (45 downto 0);
E : OUT std_logic_vector (7 downto 0);
clk : IN std_logic
);
end entity;
architecture arch_fpu of fpu is
SIGNAL d: integer;
SIGNAL mantissa1 : std_logic_vector (22 DOWNTO 0) ;
SIGNAL mantissa2 : std_logic_vector (22 DOWNTO 0) ;
begin
process(E1,E2,M1,M2,S1,S2,clk)
BEGIN
if((op="01") or (op="00")) then
E<=E1 when E1>E2 else
E2;
d<=abs(conv_integer(E1-E2));
mantissa1 <= std_logic_vector(resize(unsigned(mantissa1),mantissa1'length + d));
end if;
END process;
end arch_fpu;
You are mixing VHDL math libraries. I suggest you use either numeric_std (my preference) or std_logic_unsigned/std_logic_arith, but not both.
There are several other issues as well. You cannot assign the larger (by 'd' bits) manitissa1 value back to manitissa1, you need a target of the appropriate size. Your subtraction of E1-E2 will need some type conversion to be legal, perhaps: signed(E1) - signed(E2)
Honestly, you probably want to rethink the whole approach to what you are trying to do, especially if you expect to synthesize this code into logic.

Driving GPIO pins shared with SRAM in VHDL

I've bought a Spartan 3A development board from Micronova (http://micro-nova.com/mercury) and I've got some problems interfacing with its SRAM.
This board has 30 GPIO pins that are shared with Cypress SRAM and two pins to switch between them.
Obviously, connecting two VHDL modules (one for controlling SRAM and the other to drive GPIO) to the same pin leads to "Multiple driver error" when synthetizing.
So, to solve the problem I've created a third module as a middle controller that connects both modules with another variable for choosing which one to operate.
This works well for output, but when it comes to read input I always get 1, independently of the real value.
I don't know which pins will be used as input and which ones are for output because I would like an independent module that I can use for other projects.
This is what I got so far:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity DMA2 is
Port (
IOphys : inout STD_LOGIC_VECTOR (29 downto 0);
IOin1 : out STD_LOGIC_VECTOR (29 downto 0);
IOin2 : out STD_LOGIC_VECTOR (29 downto 0);
IOout1 : in STD_LOGIC_VECTOR (29 downto 0);
IOout2 : in STD_LOGIC_VECTOR (29 downto 0);
SwitchEn2 : in STD_LOGIC
);
end DMA2;
architecture Behavioral of DMA2 is
begin
IOin2 <= IOphys;
IOin1 <= IOphys;
IOphys <= IOout2 when SwitchEn2 = '1' else IOout1;
end Behavioral;
IOphys are the physical pins on the board, SwitchEn2 is for choosing the driving module and the others are the inputs and outputs of the modules.
You don't seem to be driving your outputs. As a starter, how about defining a tristate driver like so
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tristate is
port (
signal data_in : out std_logic;
signal data_out : in std_logic;
signal data_tristate : inout std_logic;
signal tristate_select : in std_logic
);
architecture rtl of tristate is
begin
data_in <= data_tristate;
data_tristate <= 'z' when tristate_select = '1' else data_out;
end architecture;
Then selecting between its use like so
entity arbitrate_bus
port(
-- the pins
IOphys : inout STD_LOGIC_VECTOR (29 downto 0);
IOin1 : out STD_LOGIC_VECTOR (29 downto 0);
IOout1 : in STD_LOGIC_VECTOR (29 downto 0);
IO_direction1 : in STD_LOGIC_VECTOR (29 downto 0);
IOin2 : out STD_LOGIC_VECTOR (29 downto 0);
IOout2 : in STD_LOGIC_VECTOR (29 downto 0);
IO_direction2 : in STD_LOGIC_VECTOR (29 downto 0);
SwitchEn2 : in STD_LOGIC
);
architecture like_this of arbitrate_bus is
signal input : STD_LOGIC_VECTOR (29 downto 0);
signal output_selected : STD_LOGIC_VECTOR (29 downto 0);
signal direction_selected : STD_LOGIC_VECTOR (29 downto 0);
begin
output_selected <= IOout1 when SwitchEn2 = '0' else IOout2;
direction_selected <= IO_direction1 when SwitchEn2 = '0' else IO_direction2;
g_ts: for g in output_selected'range generate
begin
u_ts: entity tristate
port map(
data_in => input(g),
data_out => output_selected(g),
data_tristate => IOphys(g),
tristate_select => direction_selected(g)
);
end generate;
IOin1 <= input;
IOin2 <= input;
end architecture;
What value are you assigning to the pins that are supposed to be inputs?
You may be able to infer proper operation if you assign 'Z' to the IOout1 and IOout2 signals when that pin is supposed to be an input, but I recommend you actually instantiate tri-state I/O pins. In addition to multiplexing the output state, you should also multiplex the output enable between the two modules, then your input code should work properly.
So each module generates output signals and a set of output enables. These signals get multiplexed and tied to the one set of physical pins, with the output enables determining which pins are inputs and which are outputs. This way, everything in the FPGA is binary logic and you are not relying on the synthesizer to infer a tri-state bus.

Resources