URL
https://opencores.org/ocsvn/avuc/avuc/trunk
Subversion Repositories avuc
Compare Revisions
- This comparison shows the changes necessary to convert path
/avuc/trunk
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/avuc.pl
29,7 → 29,7
|
$_indent = " "; |
$_command_key = "tryglspjw2u"; |
$_line_end = "\r\n"; |
$_line_end = "\n"; |
|
@predefined_ucode = ( |
"nop", |
/example/max_mem.vhd
1,25 → 1,25
-- File generated by avuc.pl (7/8/2009) |
-- |
-- 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.usm_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; |
|
|
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: |
26,299 → 26,301
+ then
+ usm_pc_ldjmp <= '1';
+ end if;
+ when USMO_JUMP_IF_MEM_DATA_LT_MAX =>
+ 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" =>
+ 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" =>
+ 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" =>
+ when "01" =>
mem_addr_s <= (others => '0');
- when others => null;
- end case;
- end if;
-end process p_usm_mem_addr_s_drv;
-
---******************************** Extra code *********************************--
+ when others => null;
+ end case;
+ end if;
+end process p_usm_mem_addr_s_drv;
+
+--******************************** Extra code *********************************--
mem_addr <= mem_addr_s;
-
-end program;
+
+end program;
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 |
|
|
-- 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" => |
|
|
-- 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 => |