Здесь я не пытаюсь убедить всех о лаконичности использования Verilog в HDL-разработке, на мой взгляд, VHDL довольно хорош, но иногда его использовать довольно геморно, особенно если нужно быстро накидать какую-то простую логику.
В качестве примера рассмотрим ситуацию, когда у нас один модуль (bench) использует второй (top), у которого 2 выходных порта.
Один из портов (С) — клок, второй — 12-битная шина данных (h). Внутри модуля объявлены параметры, которые являются условиями для присваивания значения выходному порту.
Рассмотрим как это реализовано на Verilog:
[php]
module top ( C, h );
output [ 0:0] C;
output [11:0] h;
reg [ 0:0] C;
reg [11:0] h;
reg [21:0] l;
parameter kh = 3;
parameter kl = 21’d364066;
parameter wl = 21’h100000;
initial #5
begin
C <= 0;
l <= 0;
h <= 0;
end
always #10 C = ~C;
always @(posedge C)
begin if ( l >= wl )
begin l <= l + kl — wl;
h <= h + kh + 1;
end else
begin l <= l + kl;
h <= h + kh;
end
end
endmodule
module bench;
wire [ 0:0] clock;
wire [11:0] h;
top dut ( .C(clock), .h(h) );
initial #85
begin
if ( h == 13 ) begin
$display ( «%d», h );
$display («PASSED»);
end else begin
$display ( «%d = FAIL», h );
end
$finish;
end
endmodule
[/php]
Тот же самый пример, но на VHDL :
[php]
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bench is
end entity;
architecture from_verilog of bench is
signal clock : std_logic;
signal h : unsigned(11 downto 0);
component top is
port (
C : out std_logic;
h : out unsigned(11 downto 0)
);
end component;
begin
dut: top
port map (
C => clock,
h => h
);
process is
begin
wait for 85 ms;
if Resize(h, 32) = X»0000000d» then
report «» & integer’image(To_Integer(h));
report «PASSED»;
else
report «» & integer’image(To_Integer(h)) & » = FAIL»;
end if;
report «SIMULATION FINISHED» severity failure;
wait;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity top is
port (
C : out std_logic;
h : out unsigned(11 downto 0)
);
end entity;
architecture from_verilog of top is
signal C_Reg : std_logic;
signal h_Reg : unsigned(11 downto 0);
signal l : unsigned(21 downto 0) := «0000000000000000000000»;
begin
C <= C_Reg;
h <= h_Reg;
process is
begin
wait for 5 ms;
C_Reg <= ‘0’;
h_Reg <= X»000″;
wait;
end process;
process is
begin
wait for 10 ms;
C_Reg <= not C_Reg;
end process;
process (C_Reg) is
begin if rising_edge(C_Reg) then
if l >= «0100000000000000000000» then
l <= l — «0010100111000111011110»;
h_Reg <= Resize(Resize(h_Reg, 32) + X»00000004″, 12);
else
l <= l + «0001011000111000100010»;
h_Reg <= Resize(Resize(h_Reg, 32) + X»00000003″, 12);
end if;
end if;
end process;
end architecture;
[/php]
Для решения задачи потребовалось в два раза больше строк кода и еще больше символов…
Даже я них…я не понял, но очень интересно.