using sin and cos through the lookup table in VHDL - vhdl

i'm using the sin/cos lookup table in VHDL known as sincos_lut.vhd and i'm getting an error when used with my code. I'm implementing my datapath and i need to perform sin and cos on an integer value. I do not know where my problem is but here is the code and error:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.MATH_REAL.all;
entity DFT is
port(
clk_en, clk, reset, Clock: std_logic;
t_sel,K_sel,sr_sel,si_sel,ld_t,ld_K,ld_sumreal,ld_sumimag,ld_angle: in std_logic;
N: in integer;
e: in std_logic_vector(3 downto 0);
outreal, outimag: out integer;
sig1, sig2: out std_logic
);
end DFT;
architecture str of DFT is
component Adder
Port( a, b: in integer;
f: out integer
);
end component;
component Reg
Port(
Clk: in std_logic;
ld: in std_logic;
a: in integer;
f: out integer
);
end component;
component Mul
Port(
a, b: in integer;
f: out integer
);
end component;
component LT
Port(
a, b: in integer;
sig: out std_logic
);
end component;
component Div
Port(
a, b: in integer;
f: out integer
);
end component;
component Mux
Port(
sel: in std_logic;
a, b: in integer;
f: out integer
);
end component;
component Mem
port( Clock: in std_logic;
Read: in std_logic;
Write: in std_logic;
Address: in integer;
Data_in: in integer;
Data_out: out integer
);
end component;
component sincos_lut Port
(
reset : in std_logic;
clk : in std_logic;
clk_en : in std_logic;
theta : in integer;
sin_data : out signed(integer);
cos_data : out signed(integer)
);
end component;
signal s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s30,s31,s32,s33 : integer;
constant MATH_PI : real := 3.14159_26535_89793_23846;
begin
G1: Mux port map(K_sel,0,s1,s2);
G2: Mux port map(t_sel,0,s3,s4);
G3: Reg port map(Clk,ld_K,s2,s5);
G4: Reg port map(Clk,ld_t,s4,s6);
G5: LT port map(s5,N,sig1);
G6: LT port map(s6,N,sig2);
G7: Adder port map(s5,1,s1);
G8: Adder port map(s6,1,s3);
G9: Div port map(s5,N,s7);
G10: Mul port map(s7,s6,s8);
G11: Mul port map(s8,integer(MATH_PI),s9);
G12: Mul port map(s9,2,s10);
G13: Reg port map(Clk, ld_angle,s10,s11);
G14: Mem port map(Clock,'1','0',s6,0,s12);
G15: Mem port map(Clock,'1','0',s6,0,s13);
G16: Mul port map(s12,s33,s14);
G17: Mul port map(s13,s30,s15);
G18: Adder port map(s14,s15,s16);
G19: Mux port map(sr_sel,0,s17,s18);
G20: Reg port map(Clk, ld_sumreal,s18,s19);
G21: Adder port map(s16,s19,s17);
G22: Mul port map(s12, -1,s20);
G31: sincos_lut port map(reset, clk, clk_en, s11, s30, s31);
G32: sincos_lut port map(reset, clk, clk_en, s11, s32, s33);
G23: Mul port map(s20, s30, s21);
G24: Mul port map(s13, s33, s22);
G25: Adder port map(s21, s22,s23);
G26: Mux port map(si_sel,0,s24,s25);
G27: Reg port map(Clk, ld_sumimag,s25,s26);
G28: Adder port map(s23,s26,s24);
G29: Mem port map(Clock, '0','1',s5,outimag);
G30: Mem port map(Clk, '0','1',s5,outreal);
sincos_lut
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sincos_lut is
port
(
reset : in std_logic;
clk : in std_logic;
clk_en : in std_logic;
theta : in integer;
sin_data : out signed(integer);
cos_data : out signed(integer)
);
end sincos_lut;
architecture rtl of sincos_lut is
signal theta_int : integer range 0 to 4095 := 0;
signal sin_data_int : signed(integer);
signal cos_data_int : signed(integer);
begin
theta_int <= theta;
process(reset,clk)
begin
if(reset = '1')then
sin_data_int <= to_signed(0,12);
cos_data_int <= to_signed(0,12);
elsif(rising_edge(clk)) then
if clk_en = '1' then
sin_data <= sin_data_int;
cos_data <= cos_data_int;
case theta_int is
end str;
Errors:
Error (10476): VHDL error at DFT.vhd(119): type of identifier "s30" does not agree with its usage as "SIGNED" type
Error (10558): VHDL error at DFT.vhd(119): cannot associate formal port "sin_data" of mode "out" with an expression
Error (10476): VHDL error at DFT.vhd(119): type of identifier "s31" does not agree with its usage as "SIGNED" type
Error (10558): VHDL error at DFT.vhd(119): cannot associate formal port "cos_data" of mode "out" with an expression
Line 119 is:
G31: sincos_lut port map(reset, clk, clk_en, s11, s30, s31);

Your errors are because s30 and s31 are integers and you are connecting them to a signed ports.
Kevin.

type of identifier "s30" does not agree with its usage as "SIGNED" type
This error is caused by mixing different types. The type of s30 is integer, but you are trying to map it to a port of type signed.
cannot associate formal port "sin_data" of mode "out" with an expression
This error is normally caused by "reading" an output port in your logic, but I don't see a clear reason for this error. Possibly this is related to your ports of type : signed(integer). Signed() is used for type conversion.

Your code isn't a Minimal, Complete, and Verifiable example. Note your sincos_lut doesn't analyze either.
signal s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s30,s31,s32,s33 : integer;
constant MATH_PI : real := 3.14159_26535_89793_23846;
signal signed_s30: signed (11 downto 0);
signal signed_s31: signed (11 downto 0);
signal signed_s32: signed (11 downto 0);
signal signed_s33: signed (11 downto 0);
begin
s30 <= to_integer(signed_s30);
s31 <= to_integer(signed_s31);
s32 <= to_integer(signed_s32);
s33 <= to_integer(signed_s33);
You can create signed versions of s30, s31, s32 and s33 and convert
and assign them to s30, s31, s32, s33.
Also note there were associated errors in the sincos_lut, both in port declarations and signal declarations. A type name doesn't represent a range constraint. These have been fixed by:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sincos_lut is
port
(
reset : in std_logic;
clk : in std_logic;
clk_en : in std_logic;
theta : in integer;
sin_data : out signed(11 downto 0); -- integer);
cos_data : out signed(11 downto 0) -- integer)
);
end sincos_lut;
architecture rtl of sincos_lut is
signal theta_int : integer range 0 to 4095 := 0;
signal sin_data_int : signed(11 downto 0); -- integer);
signal cos_data_int : signed(11 downto 0); -- integer);
The range of the signed values (actually the length) is determined by the to_signed function calls in the process.
Note use package numeric_std function to_integer, and in dft:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_arith.all;
-- use ieee.std_logic_unsigned.all;
-- use ieee.math_real.all;
use ieee.numeric_std.all; -- never, never mix std_logic_arith/numeric_std
-- (see sincos_lut)
Type declarations in two different packages are unique regardless of whether they have the same name and base type or not. They are not compatible. If your tool let's you it is not compliant to the VHDL standard.
G31: sincos_lut port map(reset, clk, clk_en, s11, signed_s30, signed_s31);
G32: sincos_lut port map(reset, clk, clk_en, s11, signed_s32, signed_s33);
That lops of those errors, but reveals two more:
G29: Mem port map(Clock, '0','1',s5,outimag);
G30: Mem port map(Clk, '0','1',s5,outreal);
If you look at your mem component and the positional association list in the instance port maps you'll find you're missing an integer argument for both of these representing Address.
I don't think you've revealed enough of your 'precious' IP from someone to tell what should be connected here. It's part of the price in seeking help, showing what you got. When someone tells you it isn't a minimum example, in this case it would be throwing out component instantiations and signals not connected to the actual error reports.
Also note the promiscuous use of unconstrained integers which can end up implying 32 bit values in synthesis. You should be careful and constrain everything you can.
For instance defining the range constraint for the integer address going to the Mem component defines how big the memory is.
Dummy-ing up a signal Address, an integer and inserting it in the component allows dft to finish analyzing:
G29: Mem port map(Clock, '0','1',Address,s5,outimag);
G30: Mem port map(Clk, '0','1',Address,s5,outreal);
It's not possible to elaborate your design without dummy-ing up entity and architecture pairs for all your instantiated components or eliminating them (which would lead you to a second question later).
(And you could have produced integers from the sincos_lut entity/architecture pair, but without a range constraint that would have likely been a 32 bit value).

Related

VHDL using an output from an instantiated entity in my toplevel entity

I've a VHDL code with a top entity and several other entities. Now there is an output in one of the subentities of which the value has to be brought to the toplevel entity to show it in my simulation program.
How can i do that?
TOP entity:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity multiplier is
port( Clk : in std_logic; -- Clock
A,B : in std_logic_vector(7 downto 0); -- A and B
Start : in std_logic; -- Start
Y : buffer std_logic_vector(15 downto 0); -- Result of A * B
Ready : out std_logic); -- Ready
end multiplier;
architecture structural of multiplier is
-- declaration of signals between different sub-circuits inside the multiplier
signal smInit, smCheck, smAdd, smShift, smZero, smReady, Stop : std_logic;
signal SR_A, SR_B, ADDout, MUXout : std_logic_vector(15 downto 0);
begin
io01: Ready <= smReady;
-- Instantiation of the FSM controller
sm01: entity work.FSM port map( Start, Stop, SR_A(0), Clk,
smReady, smInit, smCheck, smAdd, smShift, smZero);
-- Instantiation of the other sub-circuits and their connections
SR1: entity work.Shifter port map(smInit, smShift, '0', Clk, A, SR_A);
SR2: entity work.Shifter port map(smInit, smShift, '1', Clk, B, SR_B);
A1: entity work.Add16 port map(SR_B, Y, ADDout);
M1: entity work.Mux16 port map(smAdd, ADDout, Y, MUXout);
G1: entity work.Reg16 port map(smInit, Clk, MUXout, Y);
Z1: entity work.AllZero port map(SR_A(7 downto 0), Stop);
end structural; -- end of the multiplier architecture`
Now in the following subentity there is output S which i need to be able to call in the toplevel entity:
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Add16 is
port( A, B : in std_logic_vector(15 downto 0);
S : buffer std_logic_vector(15 downto 0));
end Add16;
architecture behavior of Add16 is
signal Addout : out std_logic_vector (15 downto 0);
begin
S <= A + B;
end behavior;
How do i do that?
VHDL-2008 has a "external names" concept, whereby a hierarchical reference is possible, so you don't need to manually route internal signals through the hierarchy if the test bench needs access to the value.
If the top-level test bench name is tb and the multiplier instance name is multiplier_e then an alias for the S port on Add16 can be created in the test bench using:
alias S_tb is <<signal .tb.multiplier_e.A1.S : std_logic_vector(15 downto 0)>>;

VHDL Selection machine error in port map

I get this error:
# Error: COMP96_0100: data_reg.vhd : (156, 35): Actual parameter type in port map does not match the port formal type "Allin".
# Error: COMP96_0100: data_reg.vhd : (158, 1): Actual parameter type in port map does not match the port formal type "Fout".
# Error: COMP96_0100: data_reg.vhd : (162, 1): Actual parameter type in port map does not match the port formal type "D".
# Error: COMP96_0100: data_reg.vhd : (163, 1): Actual parameter type in port map does not match the port formal type "Q".
I need some help, please.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ticket1 is
port (
A, B : in std_logic_vector(7 downto 0);
Clock: in std_logic;
O: out std_logic_vector(7 downto 0));
end entity;
architecture Ticketmachine of ticket1 is
component ticket_selection
port(
Allin:in bit_vector(3 downto 0);
Clk: in std_logic;
Fout: out bit_vector(7 downto 0));
end component ticket_selection;
component reg is
port(
C: in std_logic;
D: in bit_vector(7 downto 0);
Q : out bit_vector(7 downto 0));
end component reg;
component Money is
port (
Ai,Bi : in std_logic_vector(7 downto 0);
Fo: out std_logic_vector(7 downto 0));
end component money;
signal s1,s2: std_logic_vector(7 downto 0);
begin
Option: ticket_selection
port map(
Allin=>A,
Clk=>Clock,
Fout=>s1);
Cash: reg
port map(
C=>Clock,
D=>B,
Q=>s2);
Pros: Money
port map(
Ai=>s1,
Bi=>s2,
Fo=>O);
end architecture;
You should read carefully some VHDL guide for beginners. I can't recommend any (maybe someone could?), so I'll go straight to your mistakes here:
Never use std_logic_unsigned, std_logic_unsigned, and std_logic_arith. This libraries are not part of standard, and can be replaced with numeric_std.
Don't use bit or bit_vector type. Use std_logic, and std_logic_vector instead.
When you associate one vector to other, they must have equal type and length, as user1155120 and Brian Drummond wrote in comment. In particular, you can't assign std_logic_vector(7 downto 0) to bit_vector(3 downto 0).
There are probably more things done wrong here, but your question is not complete - you didn't provide any explanation what it should do, no full code, and no testbench.

VHDL incrementer "add one"

I do not how to write the truth table of this question so I can not do this question, can anyone help me understand what this question let us do? Thank you very much.
An incrementer is a combinational circuit that adds ONE to an input unsigned integer (X). The output unsigned integer (Y) has the same number of bits as the input. There is no output carry, an input string of all ‘1’s increments to all ‘0’s.
a) Write the Full-Adder Equations with inputs A0 , B0 and C0 . (aka Cin)
b) substitute with A0 = X0 , B0 = ‘0’ and C0 = ‘1 and then simplify.
c) Write the Full-Adder Equations with inputs Ai , Bi and Ci.
d) substitute with Ai = Xi , and Bi = ‘0’ and then simplify.
e) Consider a 6-bit Ripple-Adder that has A = X, B = 0 and Cin = ‘1’. Clearly this would be an incrementer. Draw a Structural Diagram of a 6-bit incrementer using the simplified circuits that you have derived in (b) and (d). (Label all instances and signals.)
VHDL can be used to model the time delay of individual gates. Please refer to your lecture notes for the BNF syntax of signal assignment. The delay format is used by simulators but is ignored by synthesizers. Use the following statements to code 2-input gates and inverters.
Code 2-input AND gates using statements with 4 ns delays,Y <= A and B after 4 ns;
Code 2-input XOR gates using the statements with 4 ns delays,Y <= A xor B after 4 ns;
Code inverters using the statements with 1 ns delays,Y <= not A after 1 ns;
Make a new directory called PLA03 and then start a new ModelSim project called PLA03.Always put Entity/Architectures in their own source files and use the Entity name as the filename.
f) Write an Entity/Architecture for your simplified circuit in (b). Name the Entity IncStage0
g) Write an Entity/Architecture for your simplified circuit in (d). Name the Entity IncStageI
h) Write an Entity named Inc6 and a Structural Architecture for your 6-bit Incrementer in (e). Remember to declare the inputs and outputs as unsigned.
library ieee;
use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
Entity IncStage0 is
port(
X:in unsigned;
S: out unsigned;
Cout: out unsigned);
End Entity IncStage0;
Architecture behaviour of IncStage0 is
Begin
S <= not X after 4 ns;
Cout <= X;
End Architecture behaviour;
library ieee;
use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
Entity IncStageI is
port(
X:in unsigned;
Cin: in unsigned;
S: out unsigned;
Cout:out unsigned);
End Entity IncStageI;
Architecture stageI of IncStageI is
Begin
S <= X xor Cin after 4 ns;
Cout <= X and Cin after 4 ns;
End Architecture stageI;
library ieee;
use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
Entity Inc6 is
port(
X:in unsigned (5 downto 0);
Y:out unsigned (5 downto 0));
End Entity Inc6;
Architecture behaviour of Inc6 is
signal C:unsigned (5 downto 0);
Component IncStage0
port(
X:in unsigned;
S: out unsigned;
Cout: out unsigned);
End Component ;
Component IncStageI
port(
X:in unsigned;
Cin: in unsigned;
S: out unsigned;
Cout:out unsigned);
End Component;
Begin
I0: IncStage0
port map(X=>X, S=>Y, Cout=>C);
I1: IncStageI
port map(X=>X, S=>Y, Cout=>C,Cin=>C);
I2: IncStageI
port map(X=>X, S=>Y, Cout=>C,Cin=>C);
I3: IncStageI
port map(X=>X, S=>Y, Cout=>C,Cin=>C);
I4: IncStageI
port map(X=>X, S=>Y, Cout=>C,Cin=>C);
I5: IncStageI
port map(X=>X, S=>Y, Cout=>C,Cin=>C);
End Architecture behaviour;
Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
Entity TBInc6 is
End Entity TBInc6;
Architecture rtl of TBInc6 is
signal tbX,tbY: unsigned(5 downto 0);
Begin
DUT: Entity work.Inc6 port map(X => tbX, Y => tbY);
Main: Process
Begin
for i in 0 to 63 loop
tbX <= to_unsigned(i,6);
wait for 30 ns;
end loop;
Wait;
End Process Main;
End Architecture rtl;
After fixing the delay in incStage0 for the NOT (should be 1 ns, not 4 ns),and changing the unconstrained subtype indications for type unsigned to type std_logic (incStage0, incStageI and their component declarations), as well as restoring the indexes for I0 through I5 you removed in your questions 5th edit and then you get:
Which looks correct compared to your instructor's supplied waveform.
Note it's hard to hit a moving target, every time you change your question the answer changes. A good indication you should be asking separate questions.
You could modify inc6 to declare signal C as:
architecture behaviour of Inc6 is
signal C:unsigned (4 downto 0);
component IncStage0
port(
X:in std_logic;
S: out std_logic;
Cout: out std_logic);
end component ;
And change the I5 instantiation:
I5: IncStageI
port map(X=>X(5), S=>Y(5), Cout=> open, Cin=>C(4));
Because you're using name association in the interface list you could simply:
I5: IncStageI
port map(X=>X(5), S=>Y(5),Cin=>C(4));
leave off mention of the carry out.
addendum
Is that means I should change every type unsigned to std_logic or
std_logic_vector?But if I try to change everything to std_logic, it
says no feasible entries for to_unsigned which is in part h code, how
to fix that?
No. unsigned is an array type. From package numeric_std (-2008):
type UNRESOLVED_UNSIGNED is array (NATURAL range <>) of STD_ULOGIC;
subtype UNSIGNED is (resolved) UNRESOLVED_UNSIGNED;
-1987, -1993, -2002:
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
While in package std_logic_1164 (-2008):
subtype STD_LOGIC is resolved STD_ULOGIC;
-1987, -1993, -2002:
SUBTYPE std_logic IS resolved std_ulogic;
In all revisions of the VHDL standard the base type of std_logic is std_ulogic, which is also the base type of the element type of the array type unsigned.
This means you can connect elements of an unsigned (representing bits) to std_logic signals, including ports. The element base type of both is std_ulogic which is a multi value representation of a bit providing both weak and strong logic level forcing and meta values representing the value of a bit:
TYPE std_ulogic IS ( 'U', -- Uninitialized
'X', -- Forcing Unknown
'0', -- Forcing 0
'1', -- Forcing 1
'Z', -- High Impedance
'W', -- Weak Unknown
'L', -- Weak 0
'H', -- Weak 1
'-' -- Don't care
);
(Also see IEEE Std 1076-2008, 16.8.2.2 The STD_LOGIC_1164 values - "The logical values '1', 'H', '0', and 'L' of type STD_ULOGIC are interpreted as representing one of two logic levels, where each logic level represents one of two distinct voltage ranges in the circuit to be synthesized.", the one of two logical values, a bit).
As you have undoubtedly discovered you can't connect an array type to a scalar type. incStage0 (I0) and inStageI (I1, I2, I3, I4 and I5) represent bits:
h) Write an Entity named Inc6 and a Structural Architecture for your 6-bit Incrementer in (e). Remember to declare the inputs and outputs as unsigned.
In the code snippets showing the use of an open for an actual on I5 the declaration for C is shown as unsigned and I5 is shown using indexed names (elements on an array object). In addition to declaring the bit slice elements of inc6 as std_logic:
entity IncStage0 is
port(
X:in std_logic;
S: out std_logic;
Cout: out std_logic);
Entity IncStageI is
port(
X:in std_logic;
Cin: in std_logic;
S: out std_logic;
Cout:out std_logic);
component IncStage0
port(
X:in std_logic;
S: out std_logic;
Cout: out std_logic);
end component ;
component IncStageI
port(
X:in std_logic;
Cin: in std_logic;
S: out std_logic;
Cout:out std_logic);
end component;
You want unsigned array values in inc6:
entity Inc6 is
port(
X:in unsigned (5 downto 0);
Y:out unsigned (5 downto 0));
architecture behaviour of Inc6 is
signal C: unsigned (4 downto 0);
And indexed array elements as actuals connected to scalar formals:
begin
I0: IncStage0
port map(X=>X(0), S=>Y(0), Cout=>C(0));
I1: IncStageI
port map(X=>X(1), S=>Y(1), Cout=>C(1),Cin=>C(0));
I2: IncStageI
port map(X=>X(2), S=>Y(2), Cout=>C(2),Cin=>C(1));
I3: IncStageI
port map(X=>X(3), S=>Y(3), Cout=>C(3),Cin=>C(2));
I4: IncStageI
port map(X=>X(4), S=>Y(4), Cout=>C(4),Cin=>C(3));
I5: IncStageI
port map(X=>X(5), S=>Y(5), Cout=> open,Cin=>C(4));
And this leaves TBinc6 as you originally displayed it using unsigned and to_unsigned without error.
And don't forget to change the time specification for delay in incStage0:
architecture behaviour of IncStage0 is
begin
S <= not X after 1 ns;
After which you can generate a wave form that shows identically to the exercise handout.
You've had more that 99 percent of the answer before running into the difference between array type and scalar types and their values. The circumlocution giving you snippets allows students taking the course to claim their work is their own. Learning and understanding, instead of simply copying.
What the question seems to be getting at, is that while you can use a general purpose adder (A + B + carry) to perform an increment, there are certain simplifications if you only need (A + 1) or (A + carry).
It appears to assume you have already been taught basic digital logic, gates, half adders and full adders. If not, this information is easily found.
So start by drawing out the "Full Adder" circuit for each bit. In Step (e), show what the simplifications are (at the gate level) when you simplify a 6 bit adder from (A + B + carry) to (A + carry).
The remaining steps will let you see if the simplified circuit is actually any faster. Looks like a good exercise in using the tools to do something really basic.

discrete cosine transform using VHDL

Am working on discrete cosine transform using VHDL. Am trying to convert the VHDL code from integer to standard logic vector. I applied some of the techniques i read online and from textbooks but it didn't work. Below is the code i tried converting.I would like the input length to be 8 bit and the output length to be 12bit.Thank you.
entity dct is
port (
Clk : in BIT;
Start : in BIT;
Din : in INTEGER;
Done : out BIT;
Dout : out INTEGER
);
end dct;
architecture behavioral of dct is
begin
process
type RF is array ( 0 to 7, 0 to 7 ) of INTEGER;
variable i, j, k : INTEGER;
variable InBlock : RF;
variable COSBlock : RF;
variable TempBlock : RF;
variable OutBlock : RF;
variable A, B, P, Sum : INTEGER;
begin
Here is the one i tried after reading some books and i keep getting errors.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dct is
port (
Clk : in std_logic;
Start : in std_logic;
Din_temp: in INTEGER;
temp := conv_std_logic_vector(Din_temp, 8);
Done : out std_logic;
Dout_temp: out INTEGER;
temp := conv_std_logic_vector(Dout_temp, 9));
end dct;
architecture behavioral of dct is
begin
process
type RF is matrix( 0 to 7, 0 to 7 ) of ;
variable i, j, k : std_logic_vector(7 downto 0);
variable InBlock : RF;
variable COSBlock : RF;
variable TempBlock : RF;
variable OutBlock : RF;
variable A, B, P, Sum : std_logic_vector(7 downto 0);
begin
seems that you combined the entity declaration with the signal assignement; this doesn't work like this! keep the entity as it was and use the type conversion functions inside your architecture. the example below shows this for Din and Dout:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dct is
port (
Clk : in BIT;
Start : in BIT;
Din : in INTEGER;
Done : out BIT;
Dout : out INTEGER
);
end dct;
architecture behavioral of dct is
signal temp_din: std_logic_vector(7 downto 0);
signal temp_dout: std_logic_vector(11 downto 0);
begin
temp_din<=std_logic_Vector(to_unsigned(Din,8));
Dout<=to_integer(unsigned(temp_dout));
...
of course, you can also use std_logic_vector directly in your entity:
entity dct is
port (
Clk : in BIT;
Start : in BIT;
Din : in std_logic_Vector(7 downto 0);
Done : out BIT;
Dout : out std_logic_vector(11 downto 0)
);
end dct;
Integers are perfectly synthesisable and work just fine as ports, so if the module you have is working satisfactorily, and synthesise correctly, leave it well alone.
It is good practice to use ranged integers : for example, if Din, Dout represent values in the range 0 to 255, create either a new integer type or a subtype for them :
type Int_8 is new Integer range 0 to 255; -- or
subtype Int_8 is Integer range 0 to 255;
(The difference is that subtypes can be freely mixed with other Integers, but accidentally mixing the new type with integer will be flagged by the compiler as an error).
The benefit of this is that synthesis won't try to create 32-bit math units where only 8 (or 3 or 19) bits is needed. Normally it does, then trims the excess bits later so it doesn't cost any more gates, it just floods the report files with "trimming redundant logic" messages...
However I am guessing the problem you have is interfacing this core with other parts of a design, implemented in a less enlightened fashion, which have std_logic_vector ports.
Then you can implement a wrapper to adapt this DCT core to a std_logic_vector environment.
I have used different techniques for different port signals : conversions in the port maps are neater, but some tools have problems (bugs) handling them. So I have used internal signals as adapters for Start and Dout, to show how you can work around such problems.
In reality, pick one or the other!
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity std_lv_dct is
port (
Clk : in std_logic;
Start : in std_logic;
Din : in std_logic_vector(7 downto 0);
Done : out std_logic;
Dout : out std_logic_vector(11 downto 0);
);
end std_lv_dct;
architecture wrapper of std_lv_dct is
Dout_int : integer range 0 to 4095;
Start_int : bit;
begin
-- internal signals as type adapters
Dout <= std_logic_vector(to_unsigned(Dout_int),11);
Start_int <= to_bit(Start);
-- direct entity instantiation for the real core
Transform : entity work.dct
port map(
Clk => to_bit(Clk),
Start => Start_int,
Din => to_integer(unsigned(Din)),
std_logic(Done) => Done,
Dout => Dout_int
);
end architecture wrapper;

VHDL gate basics

I'm learning VHDL and I've come to a halt. I'd like to create a simple gate out of smaller gates (a NAND gate here). Here's the code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity ANDGATE2 is
port(
x,y : in STD_LOGIC;
z : out STD_LOGIC
);
end ANDGATE2;
architecture ANDGATE2 of ANDGATE2 is
begin
z <= x AND y;
end ANDGATE2;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity NOTGATE1 is
port(
x : in STD_LOGIC;
z : out STD_LOGIC
);
end NOTGATE1;
architecture NOTGATE1 of NOTGATE1 is
begin
z <= NOT x;
end NOTGATE1;
library ieee;
use ieee.std_logic_1164.all;
entity NANDGATE2 is
port(
x : in STD_LOGIC;
y : in STD_LOGIC;
z : out STD_LOGIC
);
end NANDGATE2;
architecture NANDGATE2 of NANDGATE2 is
signal c, d: std_logic;
component NOTGATE1
port(
n_in : in STD_LOGIC;
n_out : out STD_LOGIC
);
end component;
component ANDGATE2
port(
a_in1, a_in2 : in STD_LOGIC;
a_out : out STD_LOGIC
);
end component;
begin
N0: ANDGATE2
port map(x, y, c);
N1: NOTGATE1
port map(c, d);
z <= d;
end NANDGATE2;
Here's the code from some tutorial I've been using as a template; it compiles with no problems.
library ieee;
use ieee.std_logic_1164.all;
-- definition of a full adder
entity FULLADDER is
port
(
a, b, c: in std_logic;
sum, carry: out std_logic
);
end FULLADDER;
architecture fulladder_behav of FULLADDER is
begin
sum <= (a xor b) xor c ;
carry <= (a and b) or (c and (a xor b));
end fulladder_behav;
-- 4-bit adder
library ieee;
use ieee.std_logic_1164.all;
entity FOURBITADD is
port
(
a, b: in std_logic_vector(3 downto 0);
Cin : in std_logic;
sum: out std_logic_vector (3 downto 0);
Cout, V: out std_logic
);
end FOURBITADD;
architecture fouradder_structure of FOURBITADD is
signal c: std_logic_vector (4 downto 0);
component FULLADDER
port
(
a, b, c: in std_logic;
sum, carry: out std_logic
);
end component;
begin
FA0: FULLADDER
port map (a(0), b(0), Cin, sum(0), c(1));
FA1: FULLADDER
port map (a(1), b(1), C(1), sum(1), c(2));
FA2: FULLADDER
port map (a(2), b(2), C(2), sum(2), c(3));
FA3: FULLADDER
port map (a(3), b(3), C(3), sum(3), c(4));
V <= c(3) xor c(4);
Cout <= c(4);
end fouradder_structure;
My code compiles with no errors, but with two warnings:
# Warning: ELAB1_0026: p2.vhd : (85, 0): There is no default binding for component "andgate2".(Port "a_in1" is not on the entity).
# Warning: ELAB1_0026: p2.vhd : (87, 0): There is no default binding for component "notgate1".(Port "n_in" is not on the entity).
What gives?
You need to use the same port names on your component and entity declarations.
Right now, for example in your NOTGATE1 entity declaration, you have input port x and output port z, but in the NANDGATE2 architecture, you declare the NOTGATE1 component to have ports n_in and n_out.
This won't cause problems during compilation, since compilation looks at a single unit at a time, and won't see the actual entities. In the elaboration phase, your tools will try to match up the entities to components, but this will fail since the ports don't match.
Not 100% sure, but I think the pins in your component declarations need to match up to the ones in your entity blocks:
component NOTGATE1
port(
x : in STD_LOGIC;
z : out STD_LOGIC
);
end component;
component ANDGATE2
port(
x,y : in STD_LOGIC;
z : out STD_LOGIC
);
Always use explicit port bindings in your port maps, like
port map(a_in1 => x,
a_in2 => y,
a_out => c);
It will make your code also more clear. In big projects it is the first rule of thumb.

Resources