URL
https://opencores.org/ocsvn/avuc/avuc/trunk
Subversion Repositories avuc
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/avuc/trunk/avuc.pl
0,0 → 1,783
#!/usr/bin/perl |
|
# Create a VHDL entity that implements a program written in a pseudo-assembler language |
# whose commands are user-defined in VHDL. |
# |
# Copyright 2008 by Fernando Blanco <ferblanco@anagramix.com> |
# |
# This source file may be used and distributed without |
# restriction provided that this copyright statement is not |
# removed from the file and that any derivative work contains |
# the original copyright notice and the associated disclaimer. |
# |
# This source file is free software; you can redistribute it |
# and/or modify it under the terms of the GNU Lesser General |
# Public License as published by the Free Software Foundation; |
# either version 2.1 of the License, or (at your option) any |
# later version. |
# |
# This source is distributed in the hope that it will be |
# useful, but WITHOUT ANY WARRANTY; without even the implied |
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
# PURPOSE. See the GNU Lesser General Public License for more |
# details. |
# |
# You should have received a copy of the GNU Lesser General |
# Public License along with this source; if not, download it |
# from http://www.gnu.org/licenses/lgpl.html |
|
|
$_indent = " "; |
$_command_key = "tryglspjw2u"; |
$_line_end = "\r\n"; |
|
@predefined_ucode = ( |
"nop", |
"jump" ); |
|
%predefined_label = ( |
"begin" => 0, |
"end" => 1); |
|
use Getopt::Std; |
use File::Basename; |
|
$prog_name='avuc.pl'; |
$ver='1.0'; |
|
getopts( 'o:dvh', \%opt ) or usage(); |
usage() if $opt{h}; |
|
sub usage() |
{ |
print "$prog_name version $ver\n"; |
print "Creates a VHDL file that runs a program based on assembler with VHDL user-defined commands\n"; |
print "Usage: $prog_name [flags] infile\n"; |
print " -o output filename\n"; |
print " -h show this help\n"; |
print " -v verbose\n"; |
print " -d debugging information\n"; |
exit; |
} |
|
$debug = 1 if $opt{d}; |
$verbose = 1 if ( $opt{v} || $opt{d} ); |
|
print "=====================================\n$prog_name version $ver\n" if ($verbose); |
# Opening input file: |
$ifile_name = $ARGV[0]; |
if ( !$ifile_name ) { usage() } |
print "Input file: $ifile_name\n" if $verbose; |
open IFILE, "< $ifile_name" or die "\'$ifile_name\' cannot be opened\n$!"; |
|
# fileparse_set_fstype(MSWin32); |
fileparse_set_fstype(Linux); |
($base_ifile, $path_ifile, $type) = fileparse($ifile_name, '\.usm'); |
|
# Opening output file: |
$ofile_name = $path_ifile . $base_ifile . '.vhd'; |
if ( $opt{o} ) { |
$ofile_name = $opt{o}; |
} |
print "Output file: $ofile_name\n" if $verbose; |
open OFILE, "> $ofile_name" or die "\'$ofile_name\' cannot be opened\n$!"; |
|
################## usm definitions file reading ###################### |
@usm_ucode = @predefined_ucode; |
$usm_cycle_bus_width = 1; |
$usmc_error_no = 0; |
$usmc_line_no = 0; |
$read_next_line = "yes"; |
while (1) { |
if ( $read_next_line =~ /yes/ ) { |
$read_line = <IFILE>; |
if (eof) { &print_message_end_usm; } |
$usmc_line_no++; |
} |
$read_next_line = "yes"; |
$_ = $read_line; |
split; |
$_ = $_[0]; |
if (/^&\$(.*)/) { |
print "Line $usmc_line_no: Command '$1' found\n" if ($verbose); |
if ($1 =~ /^end_usm$/) {last;} |
$_ = '&rd_'.$1.'(@_);'; |
@_ = eval $_; |
# print "$@" if ($@ ); |
print "Line $usmc_line_no: Error: &\$"."$1 function not implemented\n" if ($@ ); |
if ($_[0] =~ /^$_command_key$/) { |
$read_line = $_[1]; |
$read_next_line = "no"; |
} |
} |
}; |
print "File read finished. $usmc_error_no errors found\n************************\n"; |
if ( $usmc_error_no ) { exit; } |
|
######################### VHDL file writing ########################## |
|
#Header, include & entity: |
@time = localtime(time); |
$time[4] += 1; |
$time[5] += 1900; |
print OFILE "-- File generated by $prog_name ($time[3]/$time[4]/$time[5])$_line_end--$_line_end"; |
print OFILE @usm_header; |
print OFILE @usm_include; |
&wr_entity; |
|
# Architecture: |
print OFILE "$_line_end$_line_end"."architecture program of $usm_entity is$_line_end$_line_end"; |
print OFILE @usm_sig_declaration, $_line_end; |
|
$usm_opcode_bus_width = &bus_width( $#usm_ucode + keys %usm_jump_code ); |
# print "$usm_opcode_bus_width, $#usm_ucode"; exit; |
$usm_pc_bus_width = &bus_width( $usmc_prog_line_no ); |
if ($usm_pc_bus_width > $usm_data_bus_width) { $usm_data_bus_width = $usm_pc_bus_width; } |
$usm_opcode_format = "%0".$usm_opcode_bus_width."b"; |
$usm_pc_format = "%0".$usm_pc_bus_width."b"; |
$usm_data_format = "%0".$usm_data_bus_width."b"; |
&wr_sig_decl_breg; |
&wr_sig_decl_clist; |
&wr_sig_decl_llist; |
&wr_sig_decl_ulist; |
|
# Processes: |
print OFILE "$_line_end"."begin$_line_end$_line_end"; |
print OFILE "--***************************** Program processes *****************************--$_line_end"; |
&wr_proc_init; |
&wr_program; |
print OFILE "--************************** Jump & cycle processes ***************************--$_line_end"; |
&wr_jump; |
print OFILE "--**************************** Drivers processes ******************************--$_line_end"; |
&wr_drivers; |
print OFILE "--******************************** Extra code *********************************--$_line_end"; |
print OFILE @usm_extra_code; |
print OFILE "$_line_end"."end program;$_line_end"; |
exit; |
|
########################################################################## |
########################### Defined arrays ############################### |
########################################################################## |
# |
# %usm_opcode = (drivers_name_1, $uref_1, drivers_name_2, $uref_2, ... ); |
# $uref_1 = {ucode_name_1 => $cref_1, ucode_name_2 => $cref_2, ...}; |
# $cref_1 = {cycle_1 => $lref_1, cycle_2 => $lref_2, ...}; |
# $lref_1 = [line_1, line_2 ...]; |
# |
# @usm_ucode = (@predefined_ucode, ucode_name_1, ucode_name_2, ...); |
# |
# %usm_jump_code = (jump_code_name_1 => condition_1, jump_code_name_2 => condition_2, ...); |
# |
# @usm_comment = (prog_line_0_comments, prog_line_1_comments, ...); |
# |
# @usm_command = (prog_line_0_command, prog_line_1_command, ...); |
# |
# @usm_data = (prog_line_0_data, prog_line_1_data, ...); |
# |
# %usm_label = (label_name_0 => prog_line_label_0, label_name_1 => prog_line_label_1, ...}; |
# |
################################################################################## |
################################# Subroutines #################################### |
################################################################################## |
|
# Calculates the necessary bus width to hold a vector with maximum value $_[0]: |
sub bus_width { |
use integer; |
my($i, $aux) = (0, $_[0]); |
while ($aux != 1) { |
$aux /= 2; |
++$i; |
} |
return ++$i; |
} |
|
############################### Read subroutines ################################# |
|
# Reads the name of the main clock: |
sub print_message_end_usm { |
print "Error: Ending command 'end_usm' not found\n"; |
$usmc_error_no++; |
print "$usmc_error_no errors found\n************************\n"; |
exit; |
} |
|
# Reads a line, returns 1 if the first word is a command, 0 if not: |
sub line_first_word { |
my $remove_trail_blanks = $_[0]; |
$read_line = <IFILE>; |
if (eof) { &print_message_end_usm; } |
$usmc_line_no++; |
$read_line =~ s/[$_line_end]+//; # remove end of line (Linux/DOS) |
if ( $remove_trail_blanks ) { |
$read_line =~ s/\s*(.*)/\1/; |
} |
# print "$read_line#$1\n"; |
# if ( $usmc_line_no > 24 ) { exit; } |
# if ( $usmc_line_no > 90 && $usmc_line_no < 110 ) { |
|
$read_line = $read_line . $_line_end; |
@split_line = split (/\s+/, $read_line); |
$_ = $split_line[0]; |
if (/^&\$(.*)/) { |
$read_command = $1; |
return 1; |
} |
return 0; |
} |
|
# Reads the name of the main clock: |
sub rd_clock { |
$usm_main_clk = $_[1]; |
} |
|
# Reads the data bus minimum length: |
sub rd_data_bus_min_width { |
$usm_data_bus_width = $_[1]; |
} |
|
# Reads the name of the entity to create: |
sub rd_entity { |
$usm_entity = $_[1]; |
} |
|
# Reads the output file header: |
sub rd_header { |
while (1) { |
if ( &line_first_word(1) ) { |
return $_command_key, $read_line; |
} |
push(@usm_header, $read_line); |
} |
} |
|
# Reads the VHDL include text: |
sub rd_include { |
while (1) { |
if ( &line_first_word(1) ) { |
return $_command_key, $read_line; |
} |
push(@usm_include, $read_line); |
} |
} |
|
# Reads the VHDL generic parameters: |
sub rd_generic { |
while (1) { |
if ( &line_first_word(1) ) { |
return $_command_key, $read_line; |
} |
if ( $read_line !~ /^$_line_end+/ ) { push(@usm_generic, $read_line); } |
} |
} |
|
# Reads the VHDL port signals: |
sub rd_port { |
while (1) { |
if ( &line_first_word(1) ) { |
return $_command_key, $read_line; |
} |
if ( $read_line !~ /^$_line_end+/ ) { push(@usm_port, $read_line); } |
} |
} |
|
# Reads the VHDL internal signals declarations: |
sub rd_sig_declaration { |
while (1) { |
if ( &line_first_word(1) ) { |
return $_command_key, $read_line; |
} |
push(@usm_sig_declaration, $read_line); |
} |
} |
|
# Reads opcodes: |
sub rd_opcode_def { |
my $opcode, $ucode, %cycles = (), %ucodes = (); |
$opcode = $_[1]; |
while ( !&line_first_word(1) ) {} |
do { |
$ucode = $read_command; |
print "Line $usmc_line_no: Action '$ucode' found\n" if ($verbose); |
if ( $ucode !~ /^default$/ ) { |
while ( !&line_first_word(1) ) {} |
if ( $read_command !~ /^cycle_def$/ ) { |
print "Line $usmc_line_no: Error: 'cycle_def' expected instead of '$read_command'\n"; |
$usmc_error_no++; |
} |
} |
do { |
$cycle_def_no = $split_line[1]; |
# print "$opcode-$ucode-$cycle_def_no\n"; |
if ($cycle_def_no > $usm_cycle_bus_width) { $usm_cycle_bus_width = $cycle_def_no; } |
--$cycle_def_no; |
# Lines capture for this ucode: |
my @cycle_lines = (); |
while ( !&line_first_word(1) ) { |
push(@cycle_lines, $read_line); |
} |
# print "WW @cycle_lines"; |
if ( $ucode =~ /^default$/ ) { |
# default - VHDL lines: |
$ucodes{$ucode} = [ @cycle_lines ]; |
} else { |
# Hash cycle number - VHDL lines: |
$cycles{$cycle_def_no} = [ @cycle_lines ]; |
# ucode name - cycles hash: |
$ucodes{$ucode} = { %cycles }; |
} |
# opcode name - ucodes hash: |
$usm_opcode{$opcode} = { %ucodes }; |
# print "^^ $usm_opcode{$opcode}{$ucode}{$cycle_def_no}[0]"; |
} while ( $read_command =~ /^cycle_def$/ ); |
# opcode list: |
push (@usm_ucode, $ucode); |
} while ( $read_command !~ /^end_opcode_def$/ ); |
} |
|
# Reads jumps: |
sub rd_jump_opcode_def { |
my $jump_type, $jump_type; |
while ( !&line_first_word(1) ) {} |
if ( $read_command !~ /^condition$/ ) { |
print "Line $usmc_line_no: Error: 'condition' expected instead of '$read_command'\n"; |
$usmc_error_no++; |
} |
do { |
$jump_type = $split_line[1]; |
print "Line $usmc_line_no: Jump '$jump_type' found\n" if ($verbose); |
# Condition capture: |
$condition = ""; |
while ( !&line_first_word(1) ) { |
$read_line =~ s/[$_line_end]+//; |
$condition = $condition . $read_line . " "; |
} |
$usm_jump_code{$jump_type} = $condition; |
} while ( $read_command =~ /^condition$/ ); |
return $_command_key, $read_line; |
} |
|
# Reads the program: |
sub rd_prog_code { |
my $command, $label, $prog_line_no = 0; |
@usm_comment = (); |
%usm_label = %predefined_label; |
while (1) { |
if ( &line_first_word(1) ) { last; } |
# print "--$prog_line_no: $read_line--"; |
if ($read_line =~ /^$_line_end/) { next; } |
#Comments capture: |
if ($read_line =~ /^--.*/) { |
$usm_comment[$prog_line_no] .= $read_line; |
next; |
} |
#Label capture: |
if ($read_line =~ s/^(.*):\s*//) { |
$label = $1; |
if ( exists $usm_label{$label} ) { |
print "Line $usmc_line_no: Error: Label '$label' has already been defined\n"; |
$usmc_error_no++; |
} |
$usm_label{$label} = $prog_line_no; |
print "LL $prog_line_no, $label\n" if ($debug); |
} |
split( /\s+/, $read_line ); |
$usm_command[$prog_line_no] = shift @_; |
$usm_data[$prog_line_no] = "@_"; |
print "CM $usm_command[$prog_line_no]\n" if ($debug); |
print "DT $usm_data[$prog_line_no]\n" if ($debug); |
$command = $usm_command[$prog_line_no]; |
{ |
if ( grep(/^$command$/, @usm_ucode) ) { next; } |
if ( exists $usm_jump_code{$command} ) { next; } |
print "Line $usmc_line_no: Error: '$command' is not a valid opcode\n"; |
$usmc_error_no++; |
} |
$prog_line_no++; |
} |
$usmc_prog_line_no = $prog_line_no; |
$usm_label{"end"} = $usmc_prog_line_no; |
$usm_command[$usmc_prog_line_no] = "jump"; |
$usm_data[$usmc_prog_line_no] = "end"; |
&s_label_err; |
return $_command_key, $read_line; |
} |
|
# Search for label errors: |
sub s_label_err { |
foreach $index (0 .. $#usm_command ) { |
$command = $usm_command[$index]; |
if ( $command =~ /^jump$/ || |
exists $usm_jump_code{$command} ) { |
$label = $usm_data[$index]; |
if ( !exists $usm_label{$label} ) { |
print "Error: '$label' is not a valid label in\n '$command $label' (prog_code: $index)\n"; |
$usmc_error_no++; |
} |
} |
} |
} |
|
# Reads the extra VHDL code: |
sub rd_extra_code { |
while (1) { |
if ( &line_first_word(0) ) { |
return $_command_key, $read_line; |
} |
push(@usm_extra_code, $read_line); |
} |
} |
|
############################### Write subroutines ################################# |
|
# Writes a number of indentation segments: |
sub indent { |
my($i); |
for ($i = 0; $i < $_[0]; ++$i) { |
print OFILE "$_indent"; |
} |
} |
|
# Writes entity header: |
sub wr_entity { |
print OFILE "$_line_end"."entity $usm_entity is$_line_end"; |
if ( @usm_generic ) { |
&indent(1); print OFILE "generic ($_line_end"; |
foreach $line ( @usm_generic ) { &indent(2); print OFILE $line; } |
&indent(1); print OFILE ");$_line_end"; |
} |
&indent(1); print OFILE "port ($_line_end"; |
&indent(2); print OFILE "-- To start the program:$_line_end"; |
&indent(2); print OFILE "avuc_start: in std_logic;$_line_end"; |
&indent(2); print OFILE "-- To stop the program:$_line_end"; |
&indent(2); print OFILE "avuc_rst: in std_logic;$_line_end"; |
foreach $line ( @usm_port ) { &indent(2); print OFILE $line; } |
&indent(2); print OFILE "-- State of the program (running/stopped):$_line_end"; |
&indent(2); print OFILE "avuc_state: out std_logic$_line_end"; |
&indent(1); print OFILE ");$_line_end"."end $usm_entity;$_line_end"; |
} |
|
|
# Writes signal declaration of usm basic registers: |
sub wr_sig_decl_breg { |
print OFILE "-- Basic registers of usm:$_line_end"; |
printf OFILE "signal usm_opcode: std_logic_vector(%u downto 0);$_line_end", $usm_opcode_bus_width-1; |
printf OFILE "signal usm_pc: std_logic_vector(%u downto 0) := (others => '1');$_line_end", $usm_pc_bus_width-1; |
printf OFILE "signal usm_data: std_logic_vector(%u downto 0);$_line_end", $usm_data_bus_width-1; |
printf OFILE "signal usm_cyclesno: std_logic_vector(%u downto 0);$_line_end", $usm_cycle_bus_width-1; |
print OFILE "-- Cycles counter:$_line_end"; |
printf OFILE "signal usm_cy: std_logic_vector(%u downto 0);$_line_end", $usm_cycle_bus_width; |
print OFILE "-- usm_cy(0) delayed 1 clock:$_line_end"; |
print OFILE "signal usm_cy_0_d1: std_logic;$_line_end"; |
print OFILE "-- To avoid usm_cy deadlock:$_line_end"; |
print OFILE "signal usm_cy_rst: std_logic;$_line_end$_line_end"; |
} |
|
# Writes signal declaration of usm commands: |
sub wr_sig_decl_clist { |
my $ucode; |
print OFILE "-- Commands list:$_line_end"; |
foreach $index ( 0 .. $#usm_ucode ) { |
$ucode = $usm_ucode[$index]; |
print OFILE "constant USMO_" . uc($ucode) . ":$_line_end"; |
&indent(3); printf OFILE "std_logic_vector(usm_opcode'range) := \"$usm_opcode_format\";$_line_end", $index; |
} |
$index = 1; |
foreach $jump ( keys %usm_jump_code ) { |
# $ucode = $usm_jump_code{$jump}; |
print OFILE "constant USMO_" . uc($jump) . ":$_line_end"; |
&indent(3); printf OFILE "std_logic_vector(usm_opcode'range) := \"$usm_opcode_format\";$_line_end", $#usm_ucode + $index; |
++$index; |
} |
print OFILE $_line_end; |
} |
|
# Writes signal declaration of usm labels: |
sub wr_sig_decl_llist { |
my $label; |
print OFILE "-- Labels list:$_line_end"; |
foreach $index ( keys %usm_label ) { |
$label = $index; |
printf OFILE "constant USML_%s:$_line_end", uc($label); |
&indent(3); printf OFILE "std_logic_vector(usm_pc'range) := \"$usm_pc_format\";$_line_end", $usm_label{$index}; |
} |
print OFILE $_line_end; |
} |
|
# Writes signal declaration of usm ucodes: |
sub wr_sig_decl_ulist { |
my $ucode; |
print OFILE "-- usm_pc reset:$_line_end"; |
print OFILE "signal avuc_start_d: std_logic_vector(2 downto 0);$_line_end"; |
print OFILE "signal avuc_rst_d: std_logic_vector(2 downto 0);$_line_end"; |
print OFILE "signal stup_rst, stup_rst_d1: std_logic;$_line_end"; |
print OFILE "signal stup_rst_cnt: std_logic_vector(5 downto 0) := (others => '0');$_line_end"; |
print OFILE "signal usm_pc_gt_end: std_logic;$_line_end"; |
print OFILE "signal usm_pc_ldini_init_d1: std_logic;$_line_end"; |
print OFILE "signal usm_pc_ldend_init_d1: std_logic;$_line_end"; |
print OFILE "-- usm_pc microcodes:$_line_end"; |
print OFILE "signal usm_pc_inc: std_logic;$_line_end"; |
print OFILE "signal usm_pc_ldjmp: std_logic;$_line_end"; |
print OFILE "signal usm_pc_ldini: std_logic;$_line_end"; |
print OFILE "signal usm_pc_ldend: std_logic;$_line_end"; |
print OFILE "-- Remaining microcodes:$_line_end"; |
# foreach $index ( 0 .. $#usm_ucode ) { |
# $ucode = $usm_ucode[$index]; |
# if ( grep(/^$ucode$/, @predefined_ucode) ) { next; } |
# printf OFILE "signal usm_%s: std_logic;$_line_end", $ucode; |
# } |
foreach $driver ( keys %usm_opcode ) { |
foreach $ucode ( keys %{ $usm_opcode{$driver} } ) { |
if ( $ucode !~ /^default$/ ) { |
foreach $cycle_no ( keys % { $usm_opcode{$driver}->{$ucode} } ) { |
print OFILE "signal usm_$ucode"."_$cycle_no".": std_logic;$_line_end"; |
} |
} |
} |
} |
print OFILE $_line_end; |
} |
|
# Writes initial process: |
sub wr_proc_init { |
print OFILE "-- Program start/stop/state:$_line_end"; |
print OFILE "p_prog_init: process($usm_main_clk)$_line_end"; |
print OFILE "variable usm_pc_ld_init_var: std_logic;$_line_end"; |
print OFILE "begin$_line_end"; |
&indent(1); print OFILE "if rising_edge($usm_main_clk) then$_line_end"; |
&indent(2); print OFILE "-- Program start:$_line_end"; |
&indent(2); print OFILE "avuc_start_d(0) <= avuc_start;$_line_end"; |
&indent(2); print OFILE "avuc_start_d(1) <= avuc_start_d(0);$_line_end"; |
&indent(2); print OFILE "avuc_start_d(2) <= avuc_start_d(1);$_line_end"; |
&indent(2); print OFILE "usm_pc_ld_init_var := avuc_start_d(1) and not avuc_start_d(2);$_line_end"; |
&indent(2); print OFILE "usm_pc_ldini_init_d1 <= usm_pc_ld_init_var;$_line_end"; |
&indent(2); print OFILE "usm_pc_ldini <= usm_pc_ld_init_var or usm_pc_ldini_init_d1; -- 2 clocks long$_line_end"; |
&indent(2); print OFILE "-- Program stop:$_line_end"; |
&indent(2); print OFILE "if stup_rst = '1' then$_line_end"; |
&indent(3); print OFILE "stup_rst_cnt <= stup_rst_cnt + 1;$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(2); print OFILE "stup_rst <= '0';$_line_end"; |
&indent(2); print OFILE "if stup_rst_cnt(5 downto 4) /= 2 then$_line_end"; |
&indent(3); print OFILE "stup_rst <= '1';$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(2); print OFILE "stup_rst_d1 <= stup_rst;$_line_end"; |
&indent(2); print OFILE "usm_pc_gt_end <= '0';$_line_end"; |
&indent(2); print OFILE "if usm_pc > USML_END and usm_pc_gt_end = '0' then$_line_end"; |
&indent(3); print OFILE "usm_pc_gt_end <= '1';$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(2); print OFILE "avuc_rst_d(0) <= avuc_rst;$_line_end"; |
&indent(2); print OFILE "avuc_rst_d(1) <= avuc_rst_d(0);$_line_end"; |
&indent(2); print OFILE "avuc_rst_d(2) <= avuc_rst_d(1);$_line_end"; |
&indent(2); print OFILE "usm_pc_ld_init_var := usm_pc_gt_end or (not stup_rst and stup_rst_d1) or$_line_end"; |
&indent(15); print OFILE "( avuc_rst_d(1) and not avuc_rst_d(2) );$_line_end"; |
&indent(2); print OFILE "usm_pc_ldend_init_d1 <= usm_pc_ld_init_var;$_line_end"; |
&indent(2); print OFILE "usm_pc_ldend <= usm_pc_ld_init_var or usm_pc_ldend_init_d1; -- 2 clocks long$_line_end"; |
&indent(2); print OFILE "-- Program state:$_line_end"; |
&indent(2); print OFILE "avuc_state <= AVUC_STATE_RUNNING;$_line_end"; |
&indent(2); print OFILE "if usm_pc = USML_END then$_line_end"; |
&indent(3); print OFILE "avuc_state <= AVUC_STATE_STOPPED;$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(1); print OFILE "end if;$_line_end"; |
print OFILE "end process p_prog_init;$_line_end$_line_end"; |
} |
|
# Writes program: |
sub wr_program { |
my $comment, $ucode_prog, $cycle_no_max, $data; |
print OFILE "p_usm_prog_code: process(usm_pc)$_line_end"; |
print OFILE "begin$_line_end"; |
&indent(1); print OFILE "usm_data <= (others => '-');$_line_end"; |
&indent(1); print OFILE "case usm_pc is$_line_end"; |
foreach $prog_line ( 0 .. $usmc_prog_line_no ) { |
&indent(1); printf OFILE "when \"$usm_pc_format\" =>$_line_end", $prog_line; |
# Comments: |
$comment = $usm_comment[$prog_line]; |
if ( $comment ) { |
&indent(2); print OFILE "$comment"; |
} |
# usm_opcode: |
$ucode_prog = $usm_command[$prog_line]; |
&indent(2); print OFILE "usm_opcode <= USMO_".uc($ucode_prog).";$_line_end"; |
# usm_cyclesno: |
$cycle_no_max = 0; |
if ( !grep(/^$ucode_prog/, @predefined_ucode) && !exists $usm_jump_code{$ucode_prog} ) { |
outer_loop: foreach $driver (keys %usm_opcode) { |
foreach $ucode ( keys %{ $usm_opcode{$driver} } ) { |
if ( $ucode =~ /^$ucode_prog$/ ) { |
foreach $cycle_no ( keys %{$usm_opcode{$driver}->{$ucode} } ) { |
if ( $cycle_no > cycle_no_max ) { $cycle_no_max = $cycle_no; } |
} |
last outer_loop; |
} |
} |
} |
} |
&indent(2); printf OFILE "usm_cyclesno <= (%u => '1', others => '0');$_line_end", $cycle_no_max; |
# usm_data: |
$data = $usm_data[$prog_line]; |
if ( !$data =~ /\D/ ) { |
&indent(2); printf OFILE "usm_data <= \"$usm_data_format\";$_line_end", $data; |
} elsif ( exists $usm_label{$data} ) { |
&indent(2); printf OFILE "usm_data <= \"$usm_data_format\";$_line_end", $usm_label{$data}; |
} elsif ( $data ) { |
&indent(2); printf OFILE "usm_data(%u downto 0) <= %s;$_line_end", $usm_data_bus_width-1, $data; |
} |
} |
&indent(1); print OFILE "when others =>$_line_end"; |
&indent(2); print OFILE "usm_opcode <= (others => '-');$_line_end"; |
&indent(2); print OFILE "usm_cyclesno <= (others => '-');$_line_end"; |
&indent(1); print OFILE "end case;$_line_end"; |
print OFILE "end process p_usm_prog_code;$_line_end$_line_end"; |
} |
|
# Writes jump processes: |
sub wr_jump { |
# pc counter process: |
print OFILE "p_usm_pc_drv: process($usm_main_clk)$_line_end"; |
print OFILE "variable var_aux: std_logic_vector(3 downto 0);$_line_end"; |
print OFILE "begin$_line_end"; |
&indent(1); print OFILE "if rising_edge($usm_main_clk) then$_line_end"; |
&indent(2); print OFILE "-- usm_pc_inc (increment usm_pc):$_line_end"; |
&indent(2); print OFILE "usm_pc_inc <= '0';$_line_end"; |
&indent(2); print OFILE "if usm_cy = usm_cyclesno and usm_pc_ldini_init_d1 = '0' then$_line_end"; |
&indent(3); print OFILE "usm_pc_inc <= '1';$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(2); print OFILE "-- usm_pc_ldjmp (load usm_pc with usm_data):$_line_end"; |
&indent(2); print OFILE "usm_pc_ldjmp <= '0';$_line_end"; |
&indent(2); print OFILE "case usm_opcode is$_line_end"; |
&indent(2); print OFILE "when USMO_JUMP =>$_line_end"; |
&indent(3); print OFILE "usm_pc_ldjmp <= '1';$_line_end"; |
foreach $jump ( keys %usm_jump_code ) { |
&indent(2); print OFILE "when USMO_".uc($jump)." =>$_line_end"; |
&indent(3); print OFILE "if $usm_jump_code{$jump}then$_line_end", ; |
&indent(4); print OFILE "usm_pc_ldjmp <= '1';$_line_end"; |
&indent(3); print OFILE "end if;$_line_end"; |
} |
&indent(2); print OFILE "when others =>$_line_end"; |
&indent(3); print OFILE "usm_pc_ldjmp <= '0';$_line_end"; |
&indent(2); print OFILE "end case;$_line_end"; |
&indent(2); print OFILE "-- usm_pc:$_line_end"; |
&indent(2); print OFILE "usm_cy_0_d1 <= usm_cy(0) and not usm_pc_ldini_init_d1;$_line_end"; |
&indent(2); print OFILE "var_aux := usm_pc_ldini & usm_pc_ldend & (usm_pc_ldjmp and usm_cy_0_d1) & usm_pc_inc;$_line_end"; |
&indent(2); print OFILE "case var_aux is$_line_end"; |
&indent(2); print OFILE "when \"0000\" =>$_line_end"; |
&indent(3); print OFILE "null;$_line_end"; |
&indent(2); print OFILE "when \"0001\" =>$_line_end"; |
&indent(3); print OFILE "usm_pc <= usm_pc + 1;$_line_end"; |
&indent(2); print OFILE "when \"0010\" | \"0011\" =>$_line_end"; |
&indent(3); print OFILE "usm_pc <= usm_data(usm_pc'range);$_line_end"; |
&indent(2); print OFILE "when \"0100\" | \"0101\" | \"0110\" | \"0111\" =>$_line_end"; |
&indent(3); print OFILE "usm_pc <= USML_END;$_line_end"; |
&indent(2); print OFILE "when \"1000\" | \"1001\" | \"1010\" | \"1011\" | \"1100\" | \"1101\" | \"1110\" | \"1111\" => -- 1XXX$_line_end"; |
&indent(3); print OFILE "usm_pc <= USML_BEGIN;$_line_end"; |
&indent(2); print OFILE "when others =>$_line_end"; |
&indent(4); print OFILE "null;$_line_end"; |
print OFILE "-- usm_pc <= USML_BEGIN;$_line_end"; |
&indent(2); print OFILE "end case;$_line_end"; |
&indent(1); print OFILE "end if;$_line_end"; |
print OFILE "end process p_usm_pc_drv;$_line_end$_line_end"; |
# Cycle process: |
printf OFILE "p_usm_cy_drv: process(%s)$_line_end", $usm_main_clk; |
print OFILE "begin$_line_end"; |
&indent(1); printf OFILE "if rising_edge(%s) then$_line_end", $usm_main_clk; |
&indent(2); print OFILE "usm_cy_rst <= '0';$_line_end"; |
&indent(2); print OFILE "if usm_cy = 0 then$_line_end"; |
&indent(3); print OFILE "usm_cy_rst <= '1';$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(2); print OFILE "-- usm_cy:$_line_end"; |
&indent(2); print OFILE "if usm_pc_inc = '1' or (usm_pc_ldjmp = '1' and usm_cy_0_d1 = '1') or$_line_end"; |
&indent(12); print OFILE "usm_pc_ldini_init_d1 = '1' or usm_cy_rst = '1' then$_line_end"; |
&indent(3); print OFILE "usm_cy <= (0 => '1', others => '0');$_line_end"; |
&indent(2); print OFILE "else$_line_end"; |
&indent(3); print OFILE "usm_cy(0) <= '0';$_line_end"; |
&indent(3); print OFILE "for i in usm_cy'range loop$_line_end"; |
&indent(4); print OFILE "if i /= 0 then$_line_end"; |
&indent(5); print OFILE "usm_cy(i) <= usm_cy(i-1);$_line_end"; |
&indent(4); print OFILE "end if;$_line_end"; |
&indent(3); print OFILE "end loop;$_line_end"; |
&indent(2); print OFILE "end if;$_line_end"; |
&indent(1); print OFILE "end if;$_line_end"; |
print OFILE "end process p_usm_cy_drv;$_line_end$_line_end"; |
} |
|
# Writes drivers: |
sub wr_drivers { |
my %ucode_hash_uc, %ucode_hash_act, %ucode_one_hot, $index_ucode; |
foreach $driver ( keys %usm_opcode ) { |
|
# Auxiliary hashes: |
%ucode_hash_uc = %{ $usm_opcode{$driver} }; |
%ucode_hash_act = (); |
foreach $ucode ( keys %{ $usm_opcode{$driver} } ) { |
if ( $ucode !~ /^default$/ ) { |
foreach $cycle_no ( keys %{ $usm_opcode{$driver}->{$ucode} } ) { |
$ucode_hash_act{"$ucode"."_"."$cycle_no"} = $usm_opcode{$driver}->{$ucode}->{$cycle_no} ; |
} |
} |
} |
|
# Process beginning: |
print OFILE "$_line_end"; |
print OFILE "p_usm_$driver"."_drv: process($usm_main_clk)$_line_end"; |
$var_data_bus_width = scalar(keys %ucode_hash_act); |
$var_data_format = "%0".$var_data_bus_width."b"; |
printf OFILE "variable %s_var: std_logic_vector(%u downto 0);$_line_end", $driver, $var_data_bus_width-1; |
print OFILE "begin$_line_end"; |
&indent(1); print OFILE "if rising_edge($usm_main_clk) then$_line_end"; |
|
# Microcodes: |
foreach $ucode ( keys %ucode_hash_uc ) { |
if ( $ucode !~ /^default$/ ) { |
&indent(2); print OFILE "-- $ucode:$_line_end"; |
foreach $cycle_no ( keys %{ $ucode_hash_uc{$ucode} } ) { |
&indent(2); printf OFILE "usm_$ucode"."_$cycle_no <= '0';$_line_end"; |
} |
&indent(2); print OFILE "if usm_opcode = USMO_".uc($ucode)." then$_line_end"; |
foreach $cycle_no ( keys %{ $ucode_hash_uc{$ucode} } ) { |
&indent(3); printf OFILE "if usm_cy(%u) = '1' then$_line_end", $cycle_no; |
&indent(4); print OFILE "usm_$ucode"."_$cycle_no <= '1';$_line_end"; |
&indent(3); print OFILE "end if;$_line_end"; |
} |
&indent(2); print OFILE "end if;$_line_end"; |
} |
} |
|
# Actions: |
&indent(2); print OFILE "-- Actions:$_line_end"; |
&indent(2); print OFILE "$driver"."_var := "; |
$index_ucode = 0; |
foreach $ucode ( keys %ucode_hash_act ) { |
if ( $index_ucode ) { print OFILE " & "; } |
$ucode_one_hot{$ucode} = ""; |
foreach $index_one_hot ( 0 .. $var_data_bus_width-1) { |
$bit = 0; |
if ( $index_ucode == $index_one_hot ) { $bit = 1; } |
$ucode_one_hot{$ucode} .= $bit; |
} |
print OFILE "usm_$ucode"; |
++$index_ucode; |
} |
print OFILE ";$_line_end"; |
&indent(2); print OFILE "case $driver"."_var is$_line_end"; |
&indent(2); printf OFILE "when \"$var_data_format\" =>", 0; |
if ( defined($usm_opcode{$driver}->{default}) ) { |
print OFILE $_line_end; |
foreach $line ( @{ $usm_opcode{$driver}->{default} } ) { |
&indent(3); print OFILE $line; |
} |
} else { |
print OFILE " null;$_line_end"; |
} |
foreach $ucode ( keys %ucode_hash_act ) { |
&indent(2); print OFILE "when \"$ucode_one_hot{$ucode}\" =>$_line_end"; |
foreach $line ( @{ $ucode_hash_act{$ucode} } ) { |
&indent(3); print OFILE $line; |
} |
} |
&indent(2); print OFILE "when others => null;$_line_end"; |
&indent(2); print OFILE "end case;$_line_end"; |
# End process: |
&indent(1); print OFILE "end if;$_line_end"; |
print OFILE "end process p_usm_"."$driver"."_drv;$_line_end$_line_end"; |
} |
} |
|
avuc/trunk/avuc.pl
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: avuc/trunk/example/max_mem.vhd
===================================================================
--- avuc/trunk/example/max_mem.vhd (nonexistent)
+++ avuc/trunk/example/max_mem.vhd (revision 5)
@@ -0,0 +1,324 @@
+-- File generated by avuc.pl (7/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;
+ -- 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;