VHDL compliling error Testbench (ModelSim) - modelsim

I am currently doing a project in ModelSim, and Im having some trouble with the compilation. All I want to is change the value of my pin from 0 to 1, but when I compile it says that there os a error.
tool directives are not supported before VHDL 2008. I dont know why this is happening, once that my professor disponiblized a example file and I did exactly like he did. The full code is below.
-- João Vítor Abrantes - 19/0031085
-- UnB - Engenharia Elétrica
--
-- - Experimento 2 -
-- Somador Completo
-- Entity
entity testbench is end;
-- Library
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
architecture tb_sum of testbench is
-- Component
component tb_sum1
port(
W : in std_logic; --A
X : in std_logic; --B
Y : in std_logic; --Cin
Z : out std_logic; --S
Z1 : out std_logic --Cout
);
end component;
signal i_1 : std_logic;
signal i_2 : std_logic;
signal i_3 : std_logic;
Begin
S1 : tb_sum1 port map ( W => i_1 , Y => i_2 , X => i_3 , Z => open);
Cout1 : tb_sum1 port map ( W => i_1 , Y => i_2 , X => i_3 , Z1 => open);
estimulo: process
begin
wait for 5 ns; i_1 <= `1`, -- This is the part that he says the error is
wait for 5 ns;
wait for 5 ns;
wait for 5 ns;
wait for 5 ns;
wait for 5 ns;
wait for 5 ns;
wait;
end process estimulo;
end tb_sum;

you should use ' instead of ` and also need to use ; instead of ,
your code:
wait for 5 ns; i_1 <= `1`,
replace with:
wait for 5 ns; i_1 <= '1';

I searched for tool directives VHDL, and I get this:
Tool directives are arbitrary words preceded by a backtick character `.
I believe ' or " should be used here.

Related

Trying to design an 8-bit reloadable down counter

Task: Designing a 8-bit downcounter which takes an initial input value and start the downcount, and when count becomes 8'b0000_0000, it should automatically set to input value.
Ex: If given input is 8'b10010100, counter should start counting down, when value reaches 8'00000000, it should automatically reset to 8'b10010100, and again start downcount repeatedly.
For this had written a modified D flip flop using behavioral method, which works as follows:
When ld=0, output of d-flip flop q=d1 and q_bar=~d1
and when ld=1, q=d2 and q_bar=~d2
Here d2 stores the initial input values, and ld is being used as switch, i.e. when q=8'b00000000, ld=1 and sets counter output q=d2 and next cycle, ld=0 and takes d1 value.
Modified D-flip flop
module modified_d_flip_flop(q,q_bar,d1,d2,clk,ld
);
input d1,d2,clk,ld;
output q,q_bar;
reg q,q_bar;
always #(posedge clk)
begin
if(ld==0)
begin
q<=d1;
q_bar<=~d1;
end
else if(ld==1)
begin
q<=d2;
q_bar<=~d2;
end
else
begin
q<=q;
q_bar<=q_bar;
end
end
endmodule
Down Counter:
module down_counter(
input [7:0] d,
input clk,
input ld,
output [7:0] q,
output [7:0] q_bar
);
modified_d_flip_flop m_dff1 (.q(q[0]), .q_bar(q_bar[0]), .d1(q_bar[0]), .d2(d[0]), .clk(clk), .ld(ld));
modified_d_flip_flop m_dff2 (.q(q[1]), .q_bar(q_bar[1]), .d1(q_bar[1]), .d2(d[1]), .clk(q[0]), .ld(ld));
modified_d_flip_flop m_dff3 (.q(q[2]), .q_bar(q_bar[2]), .d1(q_bar[2]), .d2(d[2]), .clk(q[1]), .ld(ld));
modified_d_flip_flop m_dff4 (.q(q[3]), .q_bar(q_bar[3]), .d1(q_bar[3]), .d2(d[3]), .clk(q[2]), .ld(ld));
modified_d_flip_flop m_dff5 (.q(q[4]), .q_bar(q_bar[4]), .d1(q_bar[4]), .d2(d[4]), .clk(q[3]), .ld(ld));
modified_d_flip_flop m_dff6 (.q(q[5]), .q_bar(q_bar[5]), .d1(q_bar[5]), .d2(d[5]), .clk(q[4]), .ld(ld));
modified_d_flip_flop m_dff7 (.q(q[6]), .q_bar(q_bar[6]), .d1(q_bar[6]), .d2(d[6]), .clk(q[5]), .ld(ld));
modified_d_flip_flop m_dff8 (.q(q[7]), .q_bar(q_bar[7]), .d1(q_bar[7]), .d2(d[7]), .clk(q[6]), .ld(ld));
endmodule
Down counter Test Bench
module down_counter_tb;
reg [7:0] d;
reg clk;
reg ld;
wire [7:0] q;
wire [7:0] q_bar;
down_counter uut (
.d(d),
.clk(clk),
.ld(ld),
.q(q),
.q_bar(q_bar)
);
always #5 clk = ~clk;
initial begin
clk = 1;
ld = 1;
d = 8'b00000111;
end
initial begin
#20 ld = 0;
#20 ld = 1;
#30 ld = 0;
end
endmodule
Issue:
If initial input i.e. d2=8'b11111111, then i am getting the downcounter it works properly for the above code,
But if i give some thing like d2=8'10010011, then counter starts from 011, 010, 001 and 111, 110, 101, ........
it counts only the number of high bits from lsb + 1, if 0 is encountered next values till msb becomes x.
enter image description here
enter image description here
enter image description here
ld function too is not working as expected, when ld=0 instead of reset counter to initial input, it stops counter and starts it once ld=0.
Your code is too hard to debug because you are not designing at the proper level of abstraction. You should always use the highest level of abstraction to make the design easier to understand. Instead of designing an individual flip-flop then trying to connect them together, just design a simple counter.
With all those module instance connections, you may have a simple connection bug.
Another potential issue is a simulation race condition. Every flip-flop uses a different clock signal.
Here is a common way to design a synchronous counter. It uses the same clock for all flops of the counter:
module down_counter (
input [7:0] d,
input clk,
input ld,
output reg [7:0] q
);
always #(posedge clk) begin
if (ld || (q == 0)) begin
q <= d;
end else begin
q <= q - 1;
end
end
endmodule
module down_counter_tb;
reg [7:0] d;
reg clk;
reg ld;
wire [7:0] q;
down_counter uut (
.d(d),
.clk(clk),
.ld(ld),
.q(q)
);
always #5 clk = ~clk;
initial begin
clk = 1;
ld = 1;
d = 7;
repeat (2) #(posedge clk);
ld <= 0;
repeat (15) #(posedge clk);
ld <= 0;
d <= 8'b1001_0011;
repeat (1) #(posedge clk);
ld <= 0;
repeat (500) #(posedge clk);
$finish;
end
endmodule
By using nonblocking assignments (<=) and driving the inputs on #(posedge clk) in the testbench (as is done in the design), we also avoid race conditions in the testbench.
You didn't provide a thorough description of the ld signal. The code I showed loads the counter with the 8-bit input data (d) when ld=1. When ld=0, the counter counts down. When it reaches 0, the counter is automatically reloaded with d.
Thanks #toolic
You code surely gave me an idea. Modified it a little to solve my issue
I am trying to design a frequency divider for my project for that i needed this downcounter.
ld - Use was to make the counter reset to my expected value when ld=0 and again make ld=1 next cycle to start the downcount and again when downcounter value became 0, make ld=0 to reset the counter to expected value. This had to go on forever.
In your testbench we have to set it many times.
I just wanted to give one initial value and i wanted it to run forever.
I modified your code, to get my desired result.
I removed ld and added, initial q = 0
Down Counter
module down_counter(
input [7:0] d,
input clk,
output reg [7:0] q
);
initial q = 0;
always #(posedge clk)
begin
if (q == 0)
begin
q <= d;
end
else
begin
q <= q-1;
end
end
endmodule
Testbench:
module down_counter_tb;
// Inputs
reg [7:0] d;
reg clk;
// Outputs
wire [7:0] q;
// Instantiate the Unit Under Test (UUT)
down_counter uut (
.d(d),
.clk(clk),
.q(q)
);
always #5 clk=~clk;
initial begin
// Initialize Inputs
d = 8'b00000100;
clk = 1;
end
endmodule
Waveform:

Is it possible to declare a port as unknown sized 2d matrix in VHDL?

I need to process input ports without knowing their sizes. Here is my code below. Because I am beginner at vhdl, I am confused about this language.
I am trying to compose the code on an online playground with Aldec Riviera Pro 2020.04 simulator.
library IEEE;
use IEEE.numeric_std.all;
PACKAGE vsd is
TYPE array_2d is array(natural<>,natural<>) of INTEGER;
END PACKAGE;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.vsd.all;
entity my_conv is
port(
in_signal : in array_2d;
conv_signal : in array_2d;
result : out array_2d
);
end my_conv;
architecture arc of my_conv is
function conv_fn (conv_m, conv_n,indis_m, indis_n : natural) return INTEGER is
variable sum : INTEGER := 0;
begin
for i in conv_m-1 downto 0 loop
for j in conv_n-1 downto 0 loop
sum := sum + in_signal(i,j) * conv_signal(indis_m-i,indis_n-j);
end loop;
end loop;
return sum;
end conv_fn;
VARIABLE var_conv_m, var_conv_n, var_in_m, var_in_n : INTEGER;
VARIABLE temp_result : array_2d;
BEGIN
var_conv_m := conv_signal'length(1);
var_conv_n := conv_signal'length / var_conv_m;
for i in var_conv_m-1 downto 0 loop
for j in var_conv_n-1 downto 0 loop
temp_result(i,j) := conv_fn(var_conv_m,var_conv_n,i,j);
end loop;
end loop;
result := temp_result;
END arc;

What does the PINNAME to PINNAME data path in Xilinx ISE synthesis timing report mean?

I've written a simple DFF with the following VHDL code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity DFF is
port (d: in STD_LOGIC;
q: out STD_LOGIC;
clk: in STD_LOGIC;
reset: in STD_LOGIC);
end DFF;
architecture Behavioral of DFF is
begin
process (reset, clk) begin
if (reset = '1') then
q <= '0';
elsif (rising_edge(clk)) then
q <= d;
end if;
end process;
end Behavioral;
I subsequently run simulation and synthesis. When I examine the synthesis report, in the Timing Report section, this is present:
=========================================================================
Timing constraint: Default OFFSET OUT AFTER for Clock 'clk'
Total number of paths / destination ports: 1 / 1
-------------------------------------------------------------------------
Offset: 3.597ns (Levels of Logic = 1)
Source: q (FF)
Destination: q (PAD)
Source Clock: clk rising
Data Path: q to q
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
FDC:C->Q 1 0.447 0.579 q (q_OBUF)
OBUF:I->O 2.571 q_OBUF (q)
----------------------------------------
Total 3.597ns (3.018ns logic, 0.579ns route)
(83.9% logic, 16.1% route)
=========================================================================
What does the q to q data path signify, and what does it even mean?

VHDL directly comparing vectors

I was wondering if its possible to directly compare 2 vectors with eachother instead of just looking at them bit by bit.
For example:
entity Comparator is
port(a,b in: std_logic_vector (2 downto 0);
out1, out2 out: std_logic);
end Comparator;
architecture behavioural of Comparator1 is
begin
if a = b then
out1 <= '1'
else if /= then
out2 <= '1'
end if;
end behaviour;
Is this possible?
The answer is yes, you can compare two array types of the same type and subtype indication directly.
However your example code isn't valid.
The result of the expression a=b is boolean. You convert that to std_logic by assigning out1 and out2. An if statement in this context has to be in a process statement. Also you don't need two outputs:
architecture foo of Comparator1 is
begin
UNLABELED:
process (a,b)
begin
if a = b then
out1 <= '1';
else
out1 <= '0';
end if;
end process;
end architecture;
Alternative a concurrent signal assignment statement, a conditional signal assignment that has an equivalent process to that above:
architecture fum of Comparator1 is
begin
UNLABELED:
out1 <= '1' when a = b else '0';
end architecture;
You can also use to_integer(unsigned(a)) and threat them as integers.
For example:
IF(to_integer(unsigned(a)) < to_integer(unsigned(b))) THEN

modelsim error vsim-3421 when run from xilinx ISE 14.2

I designed and tested my VHDL code. I used ISIM (xilinx simulator) to test the code. ISIM was buggy so i switched to modelsim SE 10c.
when i run modelsim through xilinx ise i get following error in modelsim
Fatal: (vsim-3421) Value -14 is out of range -7 to 7.
my related VHDL code is
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
signal img_int : integer range -7 to 7 ;
signal add1 : integer range -7 to 7 ;
signal add2 : integer range -7 to 7 ;
process (clk)
begin
if rising_edge(clk) then
add1 <= to_integer( signed(e(0)) ) + to_integer( signed(e(1)) ) +
to_integer( signed(e(2)) ) + to_integer( signed(e(3)) );
add2 <= to_integer( signed(e(4)) ) + to_integer( signed(e(5)) ) +
to_integer( signed(e(6)) ) + to_integer( signed(e(7)) );
end if;
end process;
img_int <= add1 + add2;
the problem line is
img_int <= add1 + add2;
Can any tell why modelsim is giving this error?
Because the minimum possible value of 'add1' is -7. The same for 'add2'.
Adding 'add1' with 'add2' gives you a minimum value of -14.
That value (-14) can not be held in your 'img_int' signal.
You can extend the range of 'img_int' to e.g. integer range -14 to 14 or truncate the result.
Anyway: Try to use the 'signed' and 'unsigned' types of the liberary 'ieee.numeric_std' i.s.o. the type 'integer'.

Resources