library ieee; 
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity modMCounter is
    generic (
            M : integer := 5; -- count from 0 to M-1
            N : integer := 3   -- N bits required to count upto M i.e. 2**N >= M
    );
    
    port(
            clk, reset : in std_logic;
            complete_tick : out std_logic;
            count : out std_logic_vector(N-1 downto 0)
    );
end modMCounter;
architecture arch of modMCounter is
    signal count_reg, count_next : unsigned(N-1 downto 0);
begin
    process(clk, reset)
    begin
        if reset = '1' then 
            count_reg <= (others=>'0');
        elsif   clk'event and clk='1' then
            count_reg <= count_next;
        else  -- note that else block is not required
            count_reg <= count_reg;
        end if;
    end process;
    
    -- set count_next to 0 when maximum count is reached i.e. (M-1)
    -- otherwise increase the count
    count_next <= (others=>'0') when count_reg=(M-1) else (count_reg+1);
    
    -- Generate 'tick' on each maximum count
    complete_tick <= '1' when count_reg = (M-1) else '0';
    
    count <= std_logic_vector(count_reg); -- assign value to output port
end arch;

이 코드는 모듈로 카운터를 구현한 코드입니다. 

이 모듈러 카운터는 특정 범위 내에서 지정한 간격으로 카운트를하는 카운터로, 카운트가 최댓값에 도달하면 다시 0부터 시작합니다. 이 코드는 0부터 M-1까지 카운트하며, N비트가 필요합니다.

이 도뮬은 총 4개의 포트로 구성이됩니다. clk와 reset은 각각 카운터를 증가시키는 클록 신호와 카운터를 초기화하는 리셋 신호입니다. 

compelete_tick은 카운트가 M-1에 도달할때마다 '1'신호가 출력되는 출력 포트입니다. count는 현재 카운트 값이 출력되는 포트로,N비트의 벡터로 구성이됩니다.

clk와 reset 신호에 대한 process가 정의되어 있으며, reset이 '1'일 경우 count_reg가 0으로 초기화됩니다. clk의 edge가 감지되면 count_next 신호가 count_reg로 할당됩니다. 그 외의 경우는 count_reg를 유지합니다.

count_next는 현재 카운트 값이 M-1에 도달하면 0으로 리셋됩니다. 그렇지 않은 경우에는 카운트 값을 1씩 증가시킵니다. complete_tick은 count_reg가 M-1일 때 '1'로 할당되며, 그렇지 않은 경우에는 '0'으로 유지됩니다.

count는 count_reg 값을 N 비트의 벡터로 변환하여 출력합니다.

 

다음은 이 모듈로 카운터의 테스트벤치 코드입니다.

library ieee; 
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity modMCounter_tb is
end modMCounter_tb;


architecture arch of modMCounter_tb is
    constant M : integer := 3;  -- count upto 2 (i.e. 0 to 2)
    constant N : integer := 4;
    constant T : time := 100 ns; 

    signal clk, reset : std_logic;  -- input
    signal complete_tick : std_logic; -- output
    signal count : std_logic_vector(N-1 downto 0);  -- output

    -- total samples to store in file
    constant num_of_clocks : integer := 30; 
    signal i : integer := 0; -- loop variable
    begin

    modMCounter_unit : entity work.modMCounter
        generic map (M => M, N => N)
        port map (clk=>clk, reset=>reset, complete_tick=>complete_tick,
                    count=>count);

    -- reset = 1 for first clock cycle and then 0
    reset <= '1', '0' after T/2;

    -- continuous clock
    process 
    begin
        clk <= '0';
        wait for T/2;
        clk <= '1';
        wait for T/2;

        -- run 30 clocks
        if (i = num_of_clocks) then
           wait;
        else
            i <= i + 1;
        end if;
    end process;
end arch;

테스트벤치에서 사용되는 입력 신호는 clk와 reset입니다. clk는 일정한 주기로 반복되는 신호이며, reset은 모듈의 초기화를 수행하는데 사용됩니다.
테스트벤치에서 사용되는 출력 신호는 complete_tick과 count입니다. complete_tick은 모듈이 최대 카운트 값을 도달했을 때 생성되는 신호입니다. count는 현재 카운트 값을 나타내는 N비트 이진수 신호입니다.
테스트벤치는 시뮬레이션 시간을 T만큼 주기적으로 반복하면서, 모듈을 호출하고, 모듈이 제공하는 출력값을 파일에 저장합니다. 출력값은 이진수 형태로 저장됩니다.
테스트벤치는 초기에 reset 신호를 설정하고, 일정 주기마다 clk 신호를 생성하면서 모듈을 호출하고, 출력값을 저장하며, 시뮬레이션 시간이 끝날 때까지 반복됩니다.

'Computer_logic' 카테고리의 다른 글

Testbench  (0) 2023.04.06
Mealy & Moore VHDL code  (0) 2023.04.05
Mealy FSM & Moore FSM  (0) 2023.04.05
TCP Congestion control  (0) 2022.11.09
FLOW control  (0) 2022.11.09

+ Recent posts