Вызов модуля в Verilog и VHDL

On 12.05.2017 by nikellanjilo

Здесь я не пытаюсь убедить всех о лаконичности использования Verilog в HDL-разработке, на мой взгляд, VHDL довольно хорош, но иногда его использовать довольно геморно, особенно если нужно быстро накидать какую-то простую логику.

В качестве примера рассмотрим ситуацию, когда у нас один модуль (bench) использует второй (top), у которого 2 выходных порта.

Один из портов (С) — клок, второй — 12-битная шина данных (h). Внутри модуля объявлены параметры, которые являются условиями для присваивания значения выходному порту.

Рассмотрим как это реализовано на Verilog:

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

Тот же самый пример, но на VHDL :

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;

Для решения задачи потребовалось в два раза больше строк кода и еще больше символов…

Добавить комментарий