Z egzaminu dostałem 2*22 pkt. Myślę, że większość błędów poprawiłem i powinno być w miarę dobrze. Mimo to nie gwarantuję 100% poprawności.
Yahooku
Zad 1. 10110101
NKB= 27+25+24+22+20=128+32+16+4+1=181
U2= (-1)*27+25+24+22+20= -128 +32+16+4+1=-75
U2Fix 5,3(3 ostatnie to część dziesiętna) = (-1)*24+22+21+2-1+2-3= -16+4+2+0,5+0,125=-9,375
Zad 2.
Dodajemy wszystkie opóźnienia (rejestrów nie bierzemy pod uwagę). T=11+8+2=21ns. Przepustowość = liczba bitów wchodzących/całkowity czas „obróbki”=32bit/21ns=1520 MBit/s
Żeby zwiększyć przepustowość należy dodać rejestr potokowy po bloku o największym opóźnieniu. Dzięki temu przerywamy ścieżkę krytyczną. Rejestr ten zatrzaskuje wartość wyrzuconą przez blok i podtrzymuje ją aż do następnego taktu zegara. Mimo, że pierwszy wynik działania całego układu jest opóźniony o takt zegara układ działa szybciej, bo bloki 8 i 2ns nie czekają na wynik bloku 11ns tylko otrzymują go już z rejestru potokowego. (w czasie kiedy bloki 8 i 2ns liczą, rejestr potokowy zatrzaskuje już następną wartość z bloku 11ns).
Przepustowość = 32/10ns=3200 MBit/s
Zad 3.
Dla kompilatora porównanie i=”1-- „(„01-„) jest zawsze nieprawdziwe. (nie potrafi ogarnąć „don’t care”). Rozwiązaniem jest użycie funkcji std_match:
Irq_level <=
„11” when (std_match(i,"1--")) else {…}
Drugim sposobem jest zwykłe rozpisanie wszystkich kostek.
Irq_level <=
„11” when (i=”111" or i=”110” or i=”101” or i=”100”) else {…}
W drugiej grupie było coś na kształt:
if(…)
{…}
elseif (…)
{…}
Nie wiem dokładne o co chodziło, bo nie widziałem tego przykładu na oczy. Na pewno trzeba było zamienić elseif na if bo program powinien sprawdzać obydwa warunki a nie „albo, albo”. Trzeba było potem dopisać jeszcze else do tych if’ow, bo trzeba dostarczyć kompilatorowi wszystkie możliwości, czy jakoś tak.
Zad 4.
b) (choć d) było zdecydowanie najbardziej kuszące :)
Zad 5.
Zwykłe połączenie 2 multiplekserów (wykład 7 slajd 23). Powiedział, że interesuje go tylko to co się dzieje wewnątrz tego procesu, więc uznałem, że nie trzeba deklarować sygnałów.
Begin
Y <= b when (target=’1’) else
<= a when (target =’0’) and (sel=”00”) else
<= c when (target =’0’) and (sel=”01”) else
<= d
End;
Część II
Zad 1.
Wykład 12, slajd 21. Można było sobie dobrać dowolne długości szyn.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Zad_1 is
port(
rst : in std_logic;
clk : in std_logic;
start : in std_logic;
data : in std_logic_vector(7 downto 0);
ready : out std_logic;
out : out std_logic_vector(3 downto 0);
);
end Zad_1;
architecture RTL of Zad_1 is
type state_type is (idle, init, cmp, add, done);
signal state_reg, state_next : state_type;
signal ready_reg, ready_next : std_logic;
signal bcd_a_reg, bcd_a_next : unsigned(3 downto 0);
signal bcd_b_reg, bcd_b_next : unsigned(3 downto 0);
signal cnt_reg, cnt_next : unsigned(3 downto 0);
signal res_reg, res_next : std_logic_vector(7 downto 0);
signal out_reg, out_next : std_logic_vector(7 downto 0);
signal cnt_is_a : std_logic;
signal res_add_b, cnt_add_1 : std_logic;
signal result_store : std_logic;
process(clk, rst)
begin
if rst = '1' then
state_reg <= idle;
ready_reg <= '0';
elsif rising_edge(clk) then
state_reg <= state_next;
out_reg <= out_next;
end if;
end process;
process(state_reg, start, cnt_is_a)
begin
result_store <= '0';
ready_next <= '0';
bcd_a_reg <= (others => ‘0’);
bcd_a_next <= (others => ‘0’);
bcd_b_reg <= (others => ‘0’);
bcd_b_next <= (others => ‘0’);
res_reg <= (others => ‘0’);
res_next <= (others => ‘0’);
cnt_next <= (others =>‘0’);
cnt_reg <= (others =>‘0’);
res_add_b <=’0’;
cnt_add_1 <=’0’;
case state_reg is
when idle =>
if start = '1' then
state_next <= init;
else
state_next <= idle;
end if;
when init =>
a_load<=’1’;
b_load<=’1’;
res_res <=’1’;
cnt_res<=’1’;
state_next <=cmp;
when cmpb =>
if cnt_eq_a = '1' then
state_next <= done;
else
state_next <= add;
end if;
when add =>
res_add_b <=’1’;
cnt_add_1 <=’1’;
state_next <=cmp;
when done =>
result_store <= '1';
ready_reg <= '1';
state_next <= idle;
when others =>
state_next <= idle;
end case;
end process;
process(clk, rst)
begin
if rst = '1' then
bcd_a_reg <= (others => '0');
bcd_b_reg <= (others => '0');
cnt_reg <= (others => '0');
res_reg <= (others => '0');
elsif rising_edge(clk) then
bcd_a_reg <= bcd_a_next;
bcd_b_reg <= bcd_b_next;
cnt_reg <= cnt_next;
res_reg <= res_next;
end if;
end process;
bcd_a_next <= data when a_load =’1’; else
bcd_a_reg;
bcd_b_next <= data when b_load =’1’; esle
bcd_b_reg;
cnt_next <= (others =>’0’) when cnt_res = '1' else
cnt_reg + 1 when cnt_add_1 = '1' else
cnt_reg;
res_next <= (others => '0') when res_res = '1' else
std_logic_vector(unsigned(res_reg) + bcd_a_reg) when res_add_a = '1' else
res_reg;
cnt_is_a <= '1' when cnt_next = bcd_a_next else '0';
ready <= ready_reg;
out <= res_reg;
end RTL;
Zad 2.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cnt_mod11 is
port(
clk : in std_logic;
rst : in std_logic;
mode : in std_logic_vector(2 downto 0);
data_bus : in std_logic_vector(4 downto 0);
value : out std_logic_vector(4 downto 0)
);
end cnt_mod11;
architecture data_flow of cnt_mod11 is
constant RESET : std_logic_vector (2 downto 0) := "100";
constant LOAD : std_logic_vector (2 downto 0) := "011";
constant CNT_UP : std_logic_vector (2 downto 0) := "010";
constant CNT_DOWN : std_logic_vector (2 downto 0) := "001";
constant HOLD : std_logic_vector (2 downto 0) := "000";
signal cnt_reg, cnt_next : unsigned(4 downto 0);
begin
process (clk, rst)
begin
if (rst = '1') then
cnt_reg <= (others => '0');
elseif (rising_edge(clk)) then
cnt_reg <= cnt_next;
end if;
end process;
process(cnt_reg, mode, data_bus)
begin
case mode is
when RESET =>
cnt_next <= (others => '0');
when LOAD =>
cnt_next <= unsigned(data_bus);
when CNT_UP =>
cnt_next <= cnt_reg + 1;
end if;
when CNT_DOWN =>
cnt_next <= cnt_reg - 3;
end if;
when HOLD =>
cnt_next <= cnt_reg;
when others =>
cnt_next <= cnt_reg;
end case;
end process;
value <= std_logic_vector(cnt_reg);
end data_flow;