OpenCores
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;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.