Một câu hỏi phỏng vấn VHDL sẽ dẫn đến một số mã VHDL.
Tôi đã có dịp tìm thấy một lỗi phụ trợ ghdl llvm với việc triển khai bảng chuyển đổi trạng thái của Dave Tweed nơi tác giả của ghdl đã chắt lọc việc thực hiện trong một hàm thành 17 dòng:
type remains is (r0, r1, r2, r3, r4); -- remainder values
function mod5 (dividend: bit_vector) return boolean is
type remain_array is array (NBITS downto 0) of remains;
type branch is array (remains, bit) of remains;
constant br_table: branch := ( r0 => ('0' => r0, '1' => r1),
r1 => ('0' => r2, '1' => r3),
r2 => ('0' => r4, '1' => r0),
r3 => ('0' => r1, '1' => r2),
r4 => ('0' => r3, '1' => r4)
);
variable remaind: remains := r0;
variable tbit: bit_vector (NBITS - 1 downto 0) := dividend;
begin
for i in dividend'length - 1 downto 0 loop
remaind := br_table(remaind,tbit(i));
end loop;
return remaind = r0;
end function;
Trường hợp thử nghiệm liên quan khá nhỏ cho phép gỡ lỗi dễ dàng hơn và sử dụng các tên trạng thái tương thích với VHDL trong kiểu liệt kê vẫn còn:
(được tạo bằng Dia)
Ý tưởng ở đây là hàm (hoặc thậm chí là một chương trình VHDL ví dụ gồm 27 dòng) đủ ngắn để viết câu trả lời VHDL trong một cuộc phỏng vấn. Không cần phải lo lắng về việc làm hỏng một câu hỏi phỏng vấn đòi hỏi phải thể hiện cả kiến thức và kỹ năng, một người được phỏng vấn sẽ được bảo vệ thực hiện khi được hỏi.
(Lỗi phụ trợ llvm đã được sửa trong cam kết 1f5df6e vào hôm nay.)
Một trong những điều cần lưu ý là bảng chuyển đổi trạng thái cũng cho chúng ta biết bit thương số sẽ là '1' được hiển thị bằng cách chuyển sang trạng thái có giá trị còn lại thấp hơn (hoặc cả hai lần chuyển đổi cho r4) khi trừ 5 từ cổ tức. Điều đó có thể được mã hóa trong một bảng riêng biệt (hoặc một bảng thuộc loại bản ghi có vẻ rườm rà). Chúng tôi thực hiện điều này trong lịch sử phần cứng đồ họa xử lý độ phân giải màn hình ngang bội số 5 pixel.
Làm như vậy sẽ cho chúng ta một div / mod5 tạo ra thương số và phần còn lại:
library ieee;
use ieee.std_logic_1164.all;
entity divmod5 is
generic (
NBITS: natural := 13
);
port (
clk: in std_logic;
dividend: in std_logic_vector (NBITS - 1 downto 0);
load: in std_logic;
quotient: out std_logic_vector (NBITS - 3 downto 0);
remainder: out std_logic_vector (2 downto 0);
remzero: out std_logic
);
end entity;
architecture foo of divmod5 is
type remains is (r0, r1, r2, r3, r4); -- remainder values
type remain_array is array (NBITS downto 0) of remains;
signal remaindr: remain_array := (others => r0);
signal dividendreg: std_logic_vector (NBITS - 1 downto 0);
signal quot: std_logic_vector (NBITS - 3 downto 0);
begin
parallel:
for i in NBITS - 1 downto 0 generate
type branch is array (remains, bit) of remains;
-- Dave Tweeds state transition table:
constant br_table: branch := ( r0 => ('0' => r0, '1' => r1),
r1 => ('0' => r2, '1' => r3),
r2 => ('0' => r4, '1' => r0),
r3 => ('0' => r1, '1' => r2),
r4 => ('0' => r3, '1' => r4)
);
type qt is array (remains, bit) of std_ulogic;
-- Generate quotient bits from Dave Tweeds state machine using q_table.
-- A '1' when a remainder goes to a lower remainder or for both branches
-- of r4. A '0' for all other branches.
constant q_table: qt := ( r0 => (others => '0'),
r1 => (others => '0'),
r2 => ('0' => '0', '1' => '1'),
r3 => (others => '1'),
r4 => (others => '1')
);
signal tbit: bit;
begin
tbit <= to_bit(dividendreg(i));
remaindr(i) <= br_table(remaindr(i + 1),tbit);
do_quotient:
if i < quot'length generate
quot(i) <= q_table(remaindr(i + 1),tbit);
end generate;
end generate;
dividend_reg:
process (clk)
begin
if rising_edge(clk) then
if load = '1' then
dividendreg <= dividend;
end if;
end if;
end process;
quotient_reg:
process (clk)
begin
if rising_edge (clk) then
quotient <= quot;
end if;
end process;
remainders:
process (clk)
begin
if rising_edge(clk) then
remzero <= '0';
case remaindr(0) is
when r0 =>
remainder <= "000";
remzero <= '1';
when r1 =>
remainder <= "001";
when r2 =>
remainder <= "010";
when r3 =>
remainder <= "011";
when r4 =>
remainder <= "100";
end case;
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity divmod5_tb is
end entity;
architecture foo of divmod5_tb is
constant NBITS: integer range 0 to 13 := 8;
signal clk: std_logic := '0';
signal dividend: std_logic_vector (NBITS - 1 downto 0);
signal load: std_logic := '0';
signal quotient: std_logic_vector (NBITS - 3 downto 0);
signal remainder: std_logic_vector (2 downto 0);
signal remzero: std_logic;
signal psample: std_ulogic;
signal sample: std_ulogic;
signal done: boolean;
begin
DUT:
entity work.divmod5
generic map (NBITS)
port map (
clk => clk,
dividend => dividend,
load => load,
quotient => quotient,
remainder => remainder,
remzero => remzero
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if done'delayed(30 ns) then
wait;
end if;
end process;
STIMULI:
process
begin
for i in 0 to 2 ** NBITS - 1 loop
wait for 10 ns;
dividend <= std_logic_vector(to_unsigned(i,NBITS));
wait for 10 ns;
load <= '1';
wait for 10 ns;
load <= '0';
end loop;
wait for 15 ns;
done <= true;
wait;
end process;
SAMPLER:
process (clk)
begin
if rising_edge(clk) then
psample <= load;
sample <= psample after 4 ns;
end if;
end process;
MONITOR:
process (sample)
variable i: integer;
variable div5: integer;
variable rem5: integer;
begin
if rising_edge (sample) then
i := to_integer(unsigned(dividend));
div5 := i / 5;
assert div5 = unsigned(quotient)
report LF & HT &
"i = " & integer'image(i) &
" div 5 expected " & integer'image(div5) &
" got " & integer'image(to_integer(unsigned(quotient)))
SEVERITY ERROR;
rem5 := i mod 5;
assert rem5 = unsigned(remainder)
report LF & HT &
"i = " & integer'image(i) &
" rem 5 expected " & integer'image(rem5) &
" got " & integer'image(to_integer(unsigned(remainder)))
SEVERITY ERROR;
end if;
end process;
end architecture;
Được triển khai ở đây với một câu lệnh tạo, một câu lệnh tạo bên trong tạo ra các bit thương. Mảng remaindr cung cấp một dấu vết chuyển trạng thái:
Tất cả không có một phép toán số học.
Cũng có thể thực hiện trong một thủ tục mà không cần tất cả các thanh ghi tận dụng các tham số với chế độ tắt. Điều đó sẽ tiếp cận một số dòng tối thiểu cho một cuộc phỏng vấn.
Việc thực hiện tuần tự theo đồng hồ sẽ yêu cầu bộ đếm bit và kiểm soát dòng chảy (một flip flip flop và một vài cổng).
Có sự đánh đổi thời gian / sự phức tạp tùy thuộc vào quy mô cổ tức mà bạn cũng có thể được yêu cầu bảo vệ trong một cuộc phỏng vấn.