I have successfully been able to mix both VHDL modules and Verilog modules together. Honestly it is a lot easier then I had thought it would be. Since I could not find detailed examples of this phenomenon, I had to experiment with how it would work out. The examples that I found were all wrong, but they gave enough of a hint to figure it out on my own. I'm quite sure there are many people that need to know this so if you are here, you are in a good place.
ABSTRACT
A simple Verilog top module was crafted as a 2 bit full adder. The internal components would be a verilog one bit adder and VHDL one bit adder. They got connected in the verilog top module and were successfully testbenched and synthesized. Did I mention that I used a testbench written in vhdl to test the 2 bit FA verilog top module?
Also as a second pass, I created a simple VHDL top module that was crafted as a 2 bit full adder. The internal components would ALSO be a verilog 1 bit full adder and vhdl 1 bit full adder. They got connected in the vhdl top module and they successfully testbenched and synthesized.
CODE
Below is the code that was used to create the described 2 bit adders. Hopefully it will demonstrate how easy it is to go from one language to the other.
=====================
-- 1 bit FA in VHDL
--------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FA_VHDL is
Port ( A,B,CIN : in STD_LOGIC;
COUT,S : out STD_LOGIC);
end FA_VHDL;
architecture Behavioral of FA_VHDL is
begin
--concurrent implementation of a 1 bit full adder.
--Statements outside of a process are considered concurrent
S <= A xor B xor CIN;
COUT <= (A and B) or (A and CIN) or (B and CIN);
--Alternative implementation with a use of sensitivity list.
--This block will only execute when the items in the sensitivity list change
-- FA : process (A,B,CIN)
-- begin
-- S <= A xor B xor CIN;
-- COUT <= (A and B) or (A and CIN) or (B and CIN);
-- end process;
end Behavioral;
=====================
--1 bit FA in verilog
--------------------------------
`timescale 1ns / 1ps
module FA_v(
A,B,CIN,
COUT,S);
//------------
input A,B,CIN;
output COUT, S;
// reg COUT,S; // uncomment if using "always block"
//----
//This makes the logic happen continuously
assign S = A ^ B ^ CIN;
assign COUT = (A & B) | (A & CIN) | (B & CIN);
//Alternative implementation with a use of sensitivity list.
//This "always block" will only execute when the items in the sensitivity list change
// always @ (A or B or CIN)
// begin
// S <= A ^ B ^ CIN;
// COUT <= (A & B) | (A & CIN) | (B & CIN);
// end
endmodule
=====================
--2 bit FA in verilog with internal components: 1 bit verilog fa and 1 bit vhdl fa
--------------------------------
`timescale 1ns / 1ps
`default_nettype none
module Verilog_2bit_adder(
A2b,B2b,CIN2b,
COUT2b,S2b
);
//define pins
input [1:0] A2b,B2b;
input CIN2b;
//define ports
output COUT2b;
output [1:0] S2b;
//Specify internal wire
wire carry_w;
FA_v verilog_full_adder(
.A (A2b[0]), // ".A" specifies the Pin of the component. "A2b[0]" specifies the thing that is connecting to that pin
.B (B2b[0]),
.CIN (CIN2b),
.COUT (carry_w),
.S (S2b[0])
); //for bit0
FA_VHDL VHDL_full_adder(
.A (A2b[1]),
.B (B2b[1]),
.CIN (carry_w),
.COUT (COUT2b),
.S (S2b[1])
);//for bit1
endmodule
=====================
--2 bit FA in VHDL with internal components: 1 bit verilog fa and 1 bit vhdl fa
--------------------------------
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
entity VHDL_2bit_adder is
port ( A2b : in std_logic_vector (1 downto 0);
B2b : in std_logic_vector (1 downto 0);
CIN2b : in std_logic;
COUT2b : out std_logic;
S2b : out std_logic_vector (1 downto 0));
end VHDL_2bit_adder;
architecture BEHAVIORAL of VHDL_2bit_adder is
signal carry_s : std_logic;
component FA_v
port ( A : in std_logic;
B : in std_logic;
CIN : in std_logic;
COUT : out std_logic;
S : out std_logic);
end component;
component FA_VHDL
port ( A : in std_logic;
B : in std_logic;
CIN : in std_logic;
COUT : out std_logic;
S : out std_logic);
end component;
begin
verilog_full_adder : FA_v
port map (
A=>A2b(0),
B=>B2b(0),
CIN=>CIN2b,
COUT=>carry_s,
S=>S2b(0)
);
VHDL_full_adder : FA_VHDL
port map (
A=>A2b(1),
B=>B2b(1),
CIN=>carry_s,
COUT=>COUT2b,
S=>S2b(1)
);
end BEHAVIORAL;
=====================
--vhdl test bench
--------------------------------
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY VHDL_two_bit_adder_TB IS
END VHDL_two_bit_adder_TB;
ARCHITECTURE behavior OF VHDL_two_bit_adder_TB IS
-- Component Declaration for the Unit Under Test (UUT)
--COMPONENT Verilog_2bit_adder --testing uncomment to test verilog
COMPONENT VHDL_2bit_adder
PORT(
A2b : IN std_logic_vector(1 downto 0);
B2b : IN std_logic_vector(1 downto 0);
CIN2b : IN std_logic;
COUT2b : OUT std_logic;
S2b : OUT std_logic_vector(1 downto 0)
);
END COMPONENT;
--Inputs
signal A2b : std_logic_vector(1 downto 0) := (others => '0');
signal B2b : std_logic_vector(1 downto 0) := (others => '0');
signal CIN2b : std_logic := '0';
--Outputs
signal COUT2b : std_logic;
signal S2b : std_logic_vector(1 downto 0);
signal clock : std_logic := '0';
constant clock_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
-- uut: Verilog_2bit_adder PORT MAP ( --uncomment if using verilog component
uut: VHDL_2bit_adder PORT MAP ( -- uncomment if using VHDL component
A2b => A2b,
B2b => B2b,
CIN2b => CIN2b,
COUT2b => COUT2b,
S2b => S2b
);
-- Clock process definitions
clock_process :process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
A_loop: for A in 0 to 3 loop
B_loop: for B in 0 to 3 loop
CIN_loop: for CIN in 0 to 1 loop
A2b <= conv_std_logic_vector(A, 2);
B2b <= conv_std_logic_vector(B, 2);
if CIN = 1 then
CIN2b <= '1';
else
CIN2b <= '0';
end if;
wait for clock_period;
assert (A+B+CIN = conv_integer(COUT2b&S2b)) report "This isn't right" severity error;
end loop CIN_loop;
end loop B_loop;
end loop A_loop;
-- insert stimulus here
wait;
end process;
END;
No comments:
Post a Comment