i recieved this question as a pre interview question "Draw a diagram and write the VHDL code for a module that meets the following requirements: a. Fully synchronous. b. Muxes between 11 buses where each bus is 8-bits wide. c. Has 2 cycles of latency. d. Optimized for maximum clock frequency."
ive been trying to do it myself reading my old notes and assignments i have done in university but i just don't think i'm on the right track with this. i have the code soo far posted below:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Mux is
port(
A: in STD_LOGIC_vector(7 downto 0);
B: in STD_LOGIC_vector(7 downto 0);
C: in STD_LOGIC_vector(7 downto 0);
D: in STD_LOGIC_vector(7 downto 0);
E: in STD_LOGIC_vector(7 downto 0);
F: in STD_LOGIC_vector(7 downto 0);
G: in STD_LOGIC_vector(7 downto 0);
H: in STD_LOGIC_vector(7 downto 0);
I: in STD_LOGIC_vector(7 downto 0);
J: in STD_LOGIC_vector(7 downto 0);
K: in STD_LOGIC_vector(7 downto 0);
S0: in std_LOGIC_vector(3 downto 0);
Z: out STD_LOGIC_vector(7 downto 0)
);
end Mux;
architecture func of Mux is
begin
process (A,B,C,D,E,F,G,H,I,J,K,S0)
begin
if S0="0001" then
Z<= A;
elsif S0="0010" then
Z<= B;
elsif S0="0011" then
Z<= C;
elsif S0="0100" then
Z<= D;
elsif S0="0101" then
Z<= E;
elsif S0="0110" then
Z<= F;
elsif S0="0111" then
Z<= G;
elsif S0="1000" then
Z<= H;
elsif S0="1001" then
Z<= I;
elsif S0="1010" then
Z<= J;
elsif S0="1011" then
Z<= K;
else
Z<=A;
end if;
end process;
end func;
and this is the code i have for my second file:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.std_logic_arith.all;
entity mux11test is
end entity mux11test;
architecture test of mux11test is
signal T_A: STD_LOGIC_vector(7 downto 0):="00000001";
signal T_B: STD_LOGIC_vector(7 downto 0):="00000010";
signal T_C: STD_LOGIC_vector(7 downto 0):="00000011";
signal T_D: STD_LOGIC_vector(7 downto 0):="00000100";
signal T_E: STD_LOGIC_vector(7 downto 0):="00000101";
signal T_F: STD_LOGIC_vector(7 downto 0):="00000110";
signal T_G: STD_LOGIC_vector(7 downto 0):="00000111";
signal T_H: STD_LOGIC_vector(7 downto 0):="00001000";
signal T_I: STD_LOGIC_vector(7 downto 0):="00001001";
signal T_J: STD_LOGIC_vector(7 downto 0):="00001010";
signal T_K: STD_LOGIC_vector(7 downto 0):="00001011";
signal T_S: STD_LOGIC_vector( 3 downto 0);
signal T_Z: STD_LOGIC_vector(7 downto 0);
component mux11 IS
port(
A: in STD_LOGIC_vector(7 downto 0);
B: in STD_LOGIC_vector(7 downto 0);
C: in STD_LOGIC_vector(7 downto 0);
D: in STD_LOGIC_vector(7 downto 0);
E: in STD_LOGIC_vector(7 downto 0);
F: in STD_LOGIC_vector(7 downto 0);
G: in STD_LOGIC_vector(7 downto 0);
H: in STD_LOGIC_vector(7 downto 0);
I: in STD_LOGIC_vector(7 downto 0);
J: in STD_LOGIC_vector(7 downto 0);
K: in STD_LOGIC_vector(7 downto 0);
S0: in std_LOGIC_vector(3 downto 0);
Z: out STD_LOGIC_vector(7 downto 0)
);
END COMPONENT ;
signal clk : std_LOGIC;
constant clk_period: time:=100ns;
begin
umux: Mux11 port map(T_A,T_B,T_C,T_D,T_E,T_F,T_G,T_H,T_I,T_J,T_K,T_S,T_Z);
clk_process:process
begin
clk<='0';
wait for clk_period/2;
clk <='1';
wait for clk_period/2;
end process;
PROCESS
begin
if T_S="0001" then
T_Z <= T_A ;
elsif T_S="0010" then
T_Z <= T_B ; wait for 100 ns;
elsif T_S="0011" then
T_Z <= T_C ; wait for 100 ns;
elsif T_S="0100" then
T_Z <= T_D ; wait for 100 ns;
elsif T_S="0101" then
T_Z <=T_E ; wait for 100 ns;
elsif T_S="0110" then
T_Z <= T_F ; wait for 100 ns;
elsif T_S="0111" then
T_Z <= T_G ; wait for 100 ns;
elsif T_S="1000" then
T_Z <= T_H ; wait for 100 ns;
elsif T_S="1001" then
T_Z <= T_I ; wait for 100 ns;
elsif T_S="1010" then
T_Z <= T_J ; wait for 100 ns;
elsif T_S="1011" then
T_Z <= T_K ; wait for 100 ns;
wait;
end if;
end PROCESS;
end architecture test;
is there anyone who could tell me if im on the right path and if this is fully synchronous and how would i start implementing or determining 2 cycles of latency?
I try to write a clear answer to help you.
First of all you need a clock in your design let's call it clk
.
entity Mux is
port(
clk: in std_logic;
A: in STD_LOGIC_vector(7 downto 0);
B: in STD_LOGIC_vector(7 downto 0);
C: in STD_LOGIC_vector(7 downto 0);
D: in STD_LOGIC_vector(7 downto 0);
E: in STD_LOGIC_vector(7 downto 0);
F: in STD_LOGIC_vector(7 downto 0);
G: in STD_LOGIC_vector(7 downto 0);
H: in STD_LOGIC_vector(7 downto 0);
I: in STD_LOGIC_vector(7 downto 0);
J: in STD_LOGIC_vector(7 downto 0);
K: in STD_LOGIC_vector(7 downto 0);
S0: in std_LOGIC_vector(3 downto 0);
Z: out STD_LOGIC_vector(7 downto 0));
end Mux;
The idea when you use synchronous processes is to always update your values on an edge of your clock. Let's say the rising edge. Thus your processes have to be only sensitive to your input clk
.
P : PROCESS (clk)
BEGIN
IF (rising_edge(clk)) THEN
...
END IF;
END PROCESS;
Concerning your multiplexer, your idea was good. Yet I would suggest to use a CASE statement because it is easier to read than IF ELSIF.
CASE S0 IS
WHEN "0001" => Z <= A;
WHEN "0010" => Z <= B;
...
WHEN "1011" => Z <= K;
END CASE;
EDIT : since I forgot to talk about the 2 cycles latency I'll say two words. There you need two intermediate signals (ie Z_i and Z_ii). Z_ii takes Z_i after one clock cycle and Z takes Z_ii after one clock cycle.
Z_ii <= Z_i;
Z <= Z_ii;
Of course you then need to drive Z_i (and not Z) in you process.