I have created a divided with core generator. It creates a component like the following:
component divider_core
port (
clk: IN std_logic;
rfd: OUT std_logic;
dividend: IN std_logic_VECTOR(31 downto 0);
divisor: IN std_logic_VECTOR(31 downto 0);
quotient: OUT std_logic_VECTOR(31 downto 0);
fractional: OUT std_logic_VECTOR(31 downto 0));
end component;
I wonder how I could use this divider component by some behavioral vhdl code, inside a process. Is that possible?
Thanks,
Haris
Once you have created your module you need to declare the component in the architecture section and map the ports of the component before the process.
You can see how it applies to your code below
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity declaration
architecture Behavioral of <your_entity> is
component divider_core
port (
clk: IN std_logic;
rfd: OUT std_logic;
dividend: IN std_logic_VECTOR(31 downto 0);
divisor: IN std_logic_VECTOR(31 downto 0);
quotient: OUT std_logic_VECTOR(31 downto 0);
fractional: OUT std_logic_VECTOR(31 downto 0));
end component;
begin
c1: divider_core Port Map (
clk => clk,
rfd => rfd,
dividend => dividend,
divisor => divisor,
quotient => quotient,
fractional => fractional
);
process
end process;
end Behavioral;
Include the numeric_std package (link) and use the division (/) operator.
It sounds like you want to use this division_core like a function, which is probably not possible. if you want a vhdl function that implements division, that is different from using a component.
Related
I have binary value as input and I need to convert it to hexadecimal output. How should I do this?
I'm new in here. Please advise to me.
If your signal is a multiple of 4-bits, then you can use X to indicate hex.
signal d : std_logic_vector(15 downto 0) := X"1234";
If your signal is a mixture, you can use a concatenate operator, eg., to set 18-bits to 0x12345, you could use
signal d : std_logic_vector(17 downto 0) := "01" & X"2345";
Using VHDL-2008 you can use a width specifier
signal d : std_logic_vector(17 downto 0) := 18X"12345";
You can also use conversion functions, e.g., to convert an integer value in hex format 16#12345# to std_logic_vector.
Is it possible to perform mathematical operations within the argument when calling a function?
For example:
answer = to_integer(dividend/divisor);
While Phillipe exaggerates the efficiency of the average VHDL coder, it's not a difficult thing to try.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture fum of foo is
signal dividend: unsigned (7 downto 0) := ("11111111"); -- 255
signal divisor: unsigned (7 downto 0) := ("00001111"); -- 15
signal answer: integer;
begin
process
begin
answer <= to_integer(dividend/divisor);
wait for 0 ns;
report "answer = " & integer'image(answer);
wait;
end process;
end architecture;
The result:
foo.vhdl:17:9:#0ns:(report note): answer = 17
The wait for 0 ns; allows answer to assume the value of the operation (it's a signal, and assignments don't occur when any process is executing or has not yet suspended). For 0 ns will cause a delta cycle delay.
If answer were a variable declared in the process it's value would be available immediately and the wait wouldn't be necessary.
The last wait statement without a delay prevents the process from executing repeatedly.
I have the following code snippet:
SIGNAL ALU_hilo : STD_LOGIC_VECTOR(63 downto 0);
PROCESS ( ALU_ctl, Ainput, Binput )
BEGIN
-- Select ALU operation
CASE ALU_ctl IS
-- ALU performs ALUresult = A_input AND B_input
WHEN "0000" => ALU_Internal <= Ainput AND Binput;
-- ALU performs ALUresult = A_input OR B_input
WHEN "0001" => ALU_Internal <= Ainput OR Binput;
-- ALU performs ALUresult = A_input + B_input
WHEN "0010" => ALU_Internal <= Ainput + Binput;
-- ALU performs ?
WHEN "0011" => ALU_Internal <= X"00000000";
-- ALU performs ?
WHEN "0100" => ALU_Internal <= X"00000000";
-- ALU performs ?
WHEN "0101" => ALU_Internal <= X"00000000";
-- ALU performs ALUresult = A_input - B_input
WHEN "0110" => ALU_Internal <= Ainput - Binput;
-- ALU performs SLT
WHEN "0111" => ALU_Internal <= Ainput - Binput ;
-- ALU performs MFHI
WHEN "1101" => ALU_Internal <= ALU_hilo(63 downto 32);
-- ALU performs MFLO
WHEN "1100" => ALU_Internal <= ALU_hilo(31 downto 0);
-- ALU performs MULT
when "1000" => ALU_hilo <= Ainput * Binput;
WHEN "1001" => ALU_Internal <= Binput(15 downto 0) & X"0000";
WHEN OTHERS => ALU_Internal <= X"00000000";
END CASE;
END PROCESS;
All of the other signals here are declared previously and work fine. My problem is that ALU_hilo is being overwritten with 0x0 on subsequent process calls where ALU_ctl is not "1000". How can I fix this so that ALU_hilo holds its value unless ALU_ctl is 1000?
You're creating latches for signals that are only assigned for specific conditions of one of the signals in the sensitivity list.
You're more than likely seeing an event on Ainput or Binput (or both) while ALU_ctl is still "1000".
Without controlling when you enable latches specifically, this process may not synthesize to your intended function. If you intend to create latches here you should use an enable that's only valid when all other signals used in the process are unchanging.
You could similarly us a clock edge and create registers instead of latches where ALU_ctl serves as an address to select which register is updated. It would imply that Ainput and Binput occur on the same clock.
(And processes aren't called, their execution is resumed when one of their sensitivity list elements has an event. There's an implied wait on ALU_ctl, Ainput, Binput; as the last statement of the process. A process is a sequence of statements that will repeat unless stopped.)
I keep getting a strange error in my code, it compiles fine but I keep getting a warning:
Warning: Unconnected, internal signal \s(0)D\ is promoted to input PIN.
Warning: Unconnected, internal signal \s(1)D\ is promoted to input PIN.
The code is for a basic register which resets, shifts to the left and inserts S_IN, and loads the values set into the register using Pload. Can anyone help me figure out what is wrong with it?
library IEEE;
use ieee.std_logic_1164.all;
entity special_register is
port( DATA: in std_logic_vector(3 downto 0);
Reset: in std_logic;
PLoad: in std_logic;
S_Right: in std_logic;
S_IN: in std_logic;
clock : in std_logic;
S: in std_logic_vector(1 downto 0);
D: out std_logic_vector(3 downto 0);
Q : out std_logic_vector(3 downto 0));
end special_register;
architecture behav of special_register is
begin
process(clock, data, Reset, S_IN, S, S_Right, PLoad)
begin
if rising_edge(clock) then
S(0) <= (S_Right);
S(1) <= (PLoad);
if (S(1) = '1') then
D(3) <= DATA(3);
D(2) <= DATA(2);
D(1) <= DATA(1);
D(0) <= DATA(0);
else if (S(0) = '0') then
D(0) <= Q(1);
D(1) <= Q(2);
D(2) <= Q(3);
D(3) <= S_IN;
end if;
end if;
end if;
end process;
Q(3) <= (NOT Reset) AND D(3);
Q(2) <= (NOT Reset) AND D(2);
Q(1) <= (NOT Reset) AND D(1);
Q(0) <= (NOT Reset) AND D(0);
end behav;
In addition to Brian's answer you could note that this design specification is not VHDL compliant and the presumed synthesis tool isn't either:
ghdl -a special_register.vhdl
special_register.vhdl:21:2: port "s" can't be assigned
special_register.vhdl:22:2: port "s" can't be assigned
special_register.vhdl:29:14: port "q" cannot be read
special_register.vhdl:30:14: port "q" cannot be read
special_register.vhdl:31:14: port "q" cannot be read
special_register.vhdl:37:26: port "d" cannot be read
special_register.vhdl:38:26: port "d" cannot be read
special_register.vhdl:39:26: port "d" cannot be read
special_register.vhdl:40:26: port "d" cannot be read
ghdl: compilation error
(It would seem you are trying to read an output port as well).
I am getting the following error with my code: ** Failure: (vsim-3808) Incompatible modes for port "d_out".
I specified a new component, defined its entity, connected its ports, everything seemd ok and even compiled but when I ran a tb it wrote an error that appears in the headline
this is part of the code:
signal jal_nor_out: std_logic;
jal_unit: jal_nor
port map(
data_in(5 downto 0) => instruction(31 downto 26),
d_out => jal_nor_out
);
jal_writedata_mux : Mux_2to1_xN
port map(
sel => jal_nor_out,
d_in1 => WriteData,
d_in2 => pc_inc,
d_out => data_mux_out
);
and on another file I have:
entity jal_nor is
port(
data_in : in std_logic_vector(5 downto 0);
d_out : out std_logic
);
end jal_nor;
architecture bhv of jal_nor is
begin
process (data_in)
begin
if data_in="000011" then
d_out <= '1';
else
d_out <= '0';
end if;
end process;
end bhv;
this is the Mux code
entity Mux_2to1_xN is
generic(
WIDTH : integer := 32);
port(
sel : in std_logic;
d_in1 : in std_logic_vector((WIDTH - 1) downto 0);
d_in2 : in std_logic_vector((WIDTH - 1) downto 0);
d_out : out std_logic_vector((WIDTH - 1) downto 0));
end Mux_2to1_xN;
any help?
Sounds like the compiler thinks you have told it two different things about the ports. Have you used any component declarations?
debugging advice:
Make a smaller testcase - keep chopping code out until you have the tiniest subset of the code which causes the error. Take out ports which don't matter, signals that are unused, everything else. In the process of doing this you'll find a very small code subset is causing the problem, and probably be able to fix it yourself. If not, you have a small self-contained piece of code you can post here for us to look at. Just the tiniest code, not with lots of lines commented out. And make sure what you post compiles to the same error...