URL
https://opencores.org/ocsvn/avuc/avuc/trunk
Subversion Repositories avuc
[/] [avuc/] [trunk/] [example/] [max_mem.vhd] - Rev 8
Compare with Previous | Blame | View Log
-- File generated by avuc.pl (8/8/2009) -- --------------------------------------------------------------------------------------- -- Copyright 2008 by USM -- Description: Search for the maximum number in a memory. --------------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library work; use work.avuc_pkg.all; entity max_mem is port ( -- To start the program: avuc_start: in std_logic; -- To stop the program: avuc_rst: in std_logic; -- Main clock: clk: in std_logic; -- Memory data bus: mem_data: in std_logic_vector(7 downto 0); -- Memory address bus: mem_addr: out std_logic_vector(6 downto 0); -- State of the program (running/stopped): avuc_state: out std_logic ); end max_mem; architecture program of max_mem is -- Temporary maximum number signal max_number: std_logic_vector(mem_data'range); -- Copy of output: signal mem_addr_s: std_logic_vector(mem_addr'range); -- Basic registers of usm: signal usm_opcode: std_logic_vector(2 downto 0); signal usm_pc: std_logic_vector(2 downto 0) := (others => '1'); signal usm_data: std_logic_vector(2 downto 0); signal usm_cyclesno: std_logic_vector(0 downto 0); -- Cycles counter: signal usm_cy: std_logic_vector(1 downto 0); -- usm_cy(0) delayed 1 clock: signal usm_cy_0_d1: std_logic; -- To avoid usm_cy deadlock: signal usm_cy_rst: std_logic; -- Commands list: constant USMO_NOP: std_logic_vector(usm_opcode'range) := "000"; constant USMO_JUMP: std_logic_vector(usm_opcode'range) := "001"; constant USMO_MEM_ADDR_INI: std_logic_vector(usm_opcode'range) := "010"; constant USMO_MEM_ADDR_INC: std_logic_vector(usm_opcode'range) := "011"; constant USMO_MAX_NUMBER_INI: std_logic_vector(usm_opcode'range) := "100"; constant USMO_MAX_NUMBER_ASSIGN: std_logic_vector(usm_opcode'range) := "101"; constant USMO_JUMP_IF_MEM_ADDR_EQ_LAST: std_logic_vector(usm_opcode'range) := "110"; constant USMO_JUMP_IF_MEM_DATA_LT_MAX: std_logic_vector(usm_opcode'range) := "111"; -- Labels list: constant USML_NEXT1: std_logic_vector(usm_pc'range) := "100"; constant USML_LOOP1: std_logic_vector(usm_pc'range) := "010"; constant USML_BEGIN: std_logic_vector(usm_pc'range) := "000"; constant USML_END: std_logic_vector(usm_pc'range) := "111"; -- usm_pc reset: signal avuc_start_d: std_logic_vector(2 downto 0); signal avuc_rst_d: std_logic_vector(2 downto 0); signal stup_rst, stup_rst_d1: std_logic; signal stup_rst_cnt: std_logic_vector(5 downto 0) := (others => '0'); signal usm_pc_gt_end: std_logic; signal usm_pc_ldini_init_d1: std_logic; signal usm_pc_ldend_init_d1: std_logic; -- usm_pc microcodes: signal usm_pc_inc: std_logic; signal usm_pc_ldjmp: std_logic; signal usm_pc_ldini: std_logic; signal usm_pc_ldend: std_logic; -- Remaining microcodes: signal usm_max_number_assign_0: std_logic; signal usm_max_number_ini_0: std_logic; signal usm_mem_addr_ini_0: std_logic; signal usm_mem_addr_inc_0: std_logic; begin --***************************** Program processes *****************************-- -- Program start/stop/state: p_prog_init: process(clk) variable usm_pc_ld_init_var: std_logic; begin if rising_edge(clk) then -- Program start: avuc_start_d(0) <= avuc_start; avuc_start_d(1) <= avuc_start_d(0); avuc_start_d(2) <= avuc_start_d(1); usm_pc_ld_init_var := avuc_start_d(1) and not avuc_start_d(2); usm_pc_ldini_init_d1 <= usm_pc_ld_init_var; usm_pc_ldini <= usm_pc_ld_init_var or usm_pc_ldini_init_d1; -- 2 clocks long -- Program stop: if stup_rst = '1' then stup_rst_cnt <= stup_rst_cnt + 1; end if; stup_rst <= '0'; if stup_rst_cnt(5 downto 4) /= 2 then stup_rst <= '1'; end if; stup_rst_d1 <= stup_rst; usm_pc_gt_end <= '0'; if usm_pc > USML_END and usm_pc_gt_end = '0' then usm_pc_gt_end <= '1'; end if; avuc_rst_d(0) <= avuc_rst; avuc_rst_d(1) <= avuc_rst_d(0); avuc_rst_d(2) <= avuc_rst_d(1); usm_pc_ld_init_var := usm_pc_gt_end or (not stup_rst and stup_rst_d1) or ( avuc_rst_d(1) and not avuc_rst_d(2) ); usm_pc_ldend_init_d1 <= usm_pc_ld_init_var; usm_pc_ldend <= usm_pc_ld_init_var or usm_pc_ldend_init_d1; -- 2 clocks long -- Program state: avuc_state <= AVUC_STATE_RUNNING; if usm_pc = USML_END then avuc_state <= AVUC_STATE_STOPPED; end if; end if; end process p_prog_init; p_usm_prog_code: process(usm_pc) begin usm_data <= (others => '-'); case usm_pc is when "000" => usm_opcode <= USMO_MEM_ADDR_INI; usm_cyclesno <= (0 => '1', others => '0'); when "001" => usm_opcode <= USMO_MAX_NUMBER_INI; usm_cyclesno <= (0 => '1', others => '0'); when "010" => usm_opcode <= USMO_JUMP_IF_MEM_DATA_LT_MAX; usm_cyclesno <= (0 => '1', others => '0'); usm_data <= "100"; when "011" => usm_opcode <= USMO_MAX_NUMBER_ASSIGN; usm_cyclesno <= (0 => '1', others => '0'); when "100" => usm_opcode <= USMO_JUMP_IF_MEM_ADDR_EQ_LAST; usm_cyclesno <= (0 => '1', others => '0'); usm_data <= "111"; when "101" => usm_opcode <= USMO_MEM_ADDR_INC; usm_cyclesno <= (0 => '1', others => '0'); when "110" => usm_opcode <= USMO_JUMP; usm_cyclesno <= (0 => '1', others => '0'); usm_data <= "010"; when "111" => usm_opcode <= USMO_JUMP; usm_cyclesno <= (0 => '1', others => '0'); usm_data <= "111"; when others => usm_opcode <= (others => '-'); usm_cyclesno <= (others => '-'); end case; end process p_usm_prog_code; --************************** Jump & cycle processes ***************************-- p_usm_pc_drv: process(clk) variable var_aux: std_logic_vector(3 downto 0); begin if rising_edge(clk) then -- usm_pc_inc (increment usm_pc): usm_pc_inc <= '0'; if usm_cy = usm_cyclesno and usm_pc_ldini_init_d1 = '0' then usm_pc_inc <= '1'; end if; -- usm_pc_ldjmp (load usm_pc with usm_data): usm_pc_ldjmp <= '0'; case usm_opcode is when USMO_JUMP => usm_pc_ldjmp <= '1'; when USMO_JUMP_IF_MEM_ADDR_EQ_LAST => if mem_addr_s = (mem_addr_s'range => '1') then usm_pc_ldjmp <= '1'; end if; when USMO_JUMP_IF_MEM_DATA_LT_MAX => if mem_data < max_number then usm_pc_ldjmp <= '1'; end if; when others => usm_pc_ldjmp <= '0'; end case; -- usm_pc: usm_cy_0_d1 <= usm_cy(0) and not usm_pc_ldini_init_d1; var_aux := usm_pc_ldini & usm_pc_ldend & (usm_pc_ldjmp and usm_cy_0_d1) & usm_pc_inc; case var_aux is when "0000" => null; when "0001" => usm_pc <= usm_pc + 1; when "0010" | "0011" => usm_pc <= usm_data(usm_pc'range); when "0100" | "0101" | "0110" | "0111" => usm_pc <= USML_END; when "1000" | "1001" | "1010" | "1011" | "1100" | "1101" | "1110" | "1111" => -- 1XXX usm_pc <= USML_BEGIN; when others => null; -- usm_pc <= USML_BEGIN; end case; end if; end process p_usm_pc_drv; p_usm_cy_drv: process(clk) begin if rising_edge(clk) then usm_cy_rst <= '0'; if usm_cy = 0 then usm_cy_rst <= '1'; end if; -- usm_cy: if usm_pc_inc = '1' or (usm_pc_ldjmp = '1' and usm_cy_0_d1 = '1') or usm_pc_ldini_init_d1 = '1' or usm_cy_rst = '1' then usm_cy <= (0 => '1', others => '0'); else usm_cy(0) <= '0'; for i in usm_cy'range loop if i /= 0 then usm_cy(i) <= usm_cy(i-1); end if; end loop; end if; end if; end process p_usm_cy_drv; --**************************** Drivers processes ******************************-- p_usm_max_number_drv: process(clk) variable max_number_var: std_logic_vector(1 downto 0); begin if rising_edge(clk) then -- max_number_assign: usm_max_number_assign_0 <= '0'; if usm_opcode = USMO_MAX_NUMBER_ASSIGN then if usm_cy(0) = '1' then usm_max_number_assign_0 <= '1'; end if; end if; -- max_number_ini: usm_max_number_ini_0 <= '0'; if usm_opcode = USMO_MAX_NUMBER_INI then if usm_cy(0) = '1' then usm_max_number_ini_0 <= '1'; end if; end if; -- Actions: max_number_var := usm_max_number_assign_0 & usm_max_number_ini_0; case max_number_var is when "00" => null; when "10" => max_number <= mem_data; when "01" => max_number <= (others => '0'); when others => null; end case; end if; end process p_usm_max_number_drv; p_usm_mem_addr_s_drv: process(clk) variable mem_addr_s_var: std_logic_vector(1 downto 0); begin if rising_edge(clk) then -- mem_addr_ini: usm_mem_addr_ini_0 <= '0'; if usm_opcode = USMO_MEM_ADDR_INI then if usm_cy(0) = '1' then usm_mem_addr_ini_0 <= '1'; end if; end if; -- mem_addr_inc: usm_mem_addr_inc_0 <= '0'; if usm_opcode = USMO_MEM_ADDR_INC then if usm_cy(0) = '1' then usm_mem_addr_inc_0 <= '1'; end if; end if; -- Actions: mem_addr_s_var := usm_mem_addr_inc_0 & usm_mem_addr_ini_0; case mem_addr_s_var is when "00" => null; when "10" => mem_addr_s <= mem_addr_s + 1; when "01" => mem_addr_s <= (others => '0'); when others => null; end case; end if; end process p_usm_mem_addr_s_drv; --******************************** Extra code *********************************-- mem_addr <= mem_addr_s; end program;