i've written this code for a ROM memory in a MIPS architecture:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity ROM is -- instruction memory
port(a: in STD_LOGIC_VECTOR(5 downto 0);
rd: out STD_LOGIC_VECTOR(31 downto 0));
end;
-- Memory is organized in 2^6=64 words by 32bits
-- Memory is NOT byte addressable!!
-- port a is connected to: pc(7 downto 2)
architecture synt of ROM is
type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
-- Test code from Harris book
constant mem: ramtype := (
0 => X"20020005",
1 => X"2003000c",
2 => X"2067fff7",
3 => X"00e22025",
4 => X"00642824",
5 => X"00a42820",
6 => X"10a7000a",
7 => X"0064202a",
8 => X"10800001",
9 => X"20050000",
10 => X"00e2202a",
11 => X"00853820",
12 => X"00e23822",
13 => X"ac670044",
14 => X"8c020050",
15 => X"08000011",
16 => X"20020001",
17 => X"ac020054",
others => X"00000000")
begin
rd <= mem(to_integer( unsigned(a)));
end;
When I compile my program, cadence shows me this line error:
expecting an expression of type ramtype (this happens for each line of the declaration of the constant mem.
I don't understand why...can someone help me?
Related
I am currently working with a hash array that I have sorted by its keys and values. I have been successful in splitting the hash up such that I can grab the key and value separately. I have created a loop function that iterates through the array of keys and values. Additionally, I have a most common number variable that keeps track of the hash value and ideally updates whenever it iterates through the loop and finds a value greater than the current value in the most common number variable.
This is what my code looks like:
my $MCNum = 0;
my #sorted_pairs = %counts{$word}.sort: *.kv;
loop (my $i = 0; $i < #sorted_pairs; $i++) {
say "i: ", #sorted_pairs[$i].values;
say "i+1 ",#sorted_pairs[$i+1].values;
if #sorted_pairs[$i].values < #sorted_pairs[$i+1].values {
$MCNum = #sorted_pairs[$i+1].values;
$best_word = #sorted_pairs[$i+1].keys;
say "MCNumber is: ", $MCNum;
}
Which gives this output when I run the program:
Sorted Hash Array: [90's => 1 at => 1 dance => 1 did => 1 does => 1 doesn't => 1 don't => 1 droid => 1 dubwise => 1 feat => 1 hasn't => 1 if => 1 is => 5 letters => 1 life => 1 like => 1 man => 1 me => 5 monsterman => 1 my => 2 scenes => 1 sensation => 1 so => 3 song => 1 survives => 1 theme => 1 triangle => 1 weather => 1 would => 1 y'all => 1 you => 10 your => 1]
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (5)
i: (5)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (5)
i: (5)
i+1 (1)
i: (1)
i+1 (2)
i: (2)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (3)
i: (3)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (1)
i: (1)
i+1 (10)
i: (10)
i+1 (1)
i: (1)
i+1 ()
This leads to my confusion as I assume that the value should be skipped when it encounters 1's, but when it sees 2, 5, and/or 10, the most common number variable value should be updated. Instead, I've noticed that when running the program, it either never updates as shown in the code, or it consistently updates the variables regardless of if the number is smaller or larger. What am I missing?
I think you want to be using value and key inside the loop instead of values and keys. The latter return lists and when you do a numeric comparison #sorted_pairs[$i].values < #sorted_pairs[$i+1].values you end up comparing the lengths of these lists.
Which is always one.
Also you could do something like :
my $MCNum = 0;
my #sorted_pairs = %counts{$word}.sort.rotor(2 => -1).map(*.kv);
for my $a, $b ( #sorted_pairs ) {
if $a.value < $b.value {
$MCNum = $b.value;
$best_word = $b.key;
say "MCNumber is: ", $MCNum;
}
}
rotor splits a list like thing into sub lists and if you set the cycle skip length to a negative it skips back an element so.
(1,2,3,4,5).rotor(2 => -1) ~~ ((1,2),(2,3),(3,4),(4,5))
Generally if I see an old school C style loop in Raku I figure something can be simplified. ;)
I'm uncertain as to the question, but it might be that you're getting involved with arrays too early in your workflow.
Let's say you have a list of word frequencies from here:
https://stackoverflow.com/a/72053359/7270649
I => 8
the => 7
and => 6
of => 4
to => 4
a => 4
If you use .put instead of .say in the code-producing output above, you get tab-separated output instead. A one-liner can take that tab-separated output easily and process it for you. Lets say we concatenate the output, so we have 2 copies, with the second copy's values incremented by +1:
I 8
the 7
and 6
to 4
of 4
a 4
I 9
the 8
and 7
to 5
of 5
a 5
Appending into a hash (%counts) gives us the following (blank spaces added for clarity):
~$ raku -e 'my %counts; for lines.map(*.words) { %counts.=append($_) }; \
.say for %counts.sort: -*.value.max;' file
I => [8 9]
the => [7 8]
and => [6 7]
to => [4 5]
a => [4 5]
of => [4 5]
From the code above, all you need is an extra statement to either 1). overwrite hash values (conditionally) with a single max value per key or 2. overwrite hash values (conditionally) with a single sum value per key:
#Max
~$ raku -e 'my %counts; for lines.map(*.words) { %counts.=append($_) }; \
for %counts.kv -> $k,$v { if $v.elems > 1 {%counts{$k} = $v.max }}; \
.say for %counts.sort: -*.value;' file
I => 9
the => 8
and => 7
to => 5
a => 5
of => 5
#Sum
~$ raku -e 'my %counts; for lines.map(*.words) { %counts.=append($_) }; \
for %counts.kv -> $k,$v { if $v.elems > 1 {%counts{$k} = $v.sum }}; \
.say for %counts.sort: -*.value;' file
I => 17
the => 15
and => 13
of => 9
a => 9
to => 9
Then...you can assign to an array. So maybe this has been helpful, at least to give you a few more 'strategic' options regarding hashes (and eventually...arrays).
https://docs.raku.org/language/hashmap#In_place_editing_of_values
I am trying to initialize the VHDL array of size 4 with all zeros. Please let me know how can I do that?
entity js is
port (
clk: in std_logic; ---------- clock
S1_vec : in t_1d_array; ---------- S1 vector/array of cross-section 4 [0 0 0 0]
S2_vec : in t_1d_array; ---------- S2 Vector/array of cross-section 4 [0 0 0 0]
J_outp : out integer
);
end js;
I am gettting two array one user and one ads I have to make another one by merging these two arrays in such a way that after every five users i will get one ad. Thanks in advance.
I like using Laravel's collections for stuff like this:
$users = range(0, 19); // users are numbers
$ads = range('a', 'd'); // ads are letters
$users = collect($users); // create a Collection from the array
$ads = collect($ads);
$result = $users->chunk(5) // break into chunks of five
->map(function($chunk) use (&$ads){
return $chunk->push($ads->shift()); // append an ad to each chunk
})->flatten() // combine all the chunks back together
->toArray(); // change the Collection back to an array
dump($result);
Gives:
array:24 [
0 => 0
1 => 1
2 => 2
3 => 3
4 => 4
5 => "a"
6 => 5
7 => 6
8 => 7
9 => 8
10 => 9
11 => "b"
12 => 10
13 => 11
14 => 12
15 => 13
16 => 14
17 => "c"
18 => 15
19 => 16
20 => 17
21 => 18
22 => 19
23 => "d"
]
I have some types like this :
Type MyCharacters is ('0', '1' ... '9', 'A', 'B', ... 'Z');
Type CharArray_8 is array(1 to 8) of MyCharacters;
Type CharArray_16 is array(1 to 16) of MyCharacters;
Type CharArray_32 is array(1 to 32) of MyCharacters;
and 4 Signals with this types :
Signal S1, S2 : CharArray_8;
Signal S3 : CharArray_16;
Signal S : CharArray_32;
I want to concatinate S1, S2 and S3 and assign the result to S, like this :
S <= S1 & S2 & S3;
but this code is wrong and have error, how I should concatenate them ?
Should Array types be declared as SubType of MyCharacters ?
but this code is wrong and have error, how I should concatenate them ?
There isn't an implicitly declared concatenation operator (&) defined for multiple array types. You need to either declare an overload operator allowing different types with the same element types to be concatenated (which is burdensome, requiring at least three functions for each possible combination) or make the array values the same type either by using type conversion or as in these first two answers declaring a single unbound array type. The array types are eligible for type conversion, having index ranges compatible with type S3 and the same element type.
Should Array types be declared as SubType of MyCharacters ?
In addiition to named subtypes object declarations shown by Renaud Pacalet subtypes can be defined through subtype indications (a type mark and a constraint) in object declarations:
type mychararray is array(natural range <>) of MyCharacters;
signal S1, S2: mychararray(1 to 8);
signal S3: mychararray(1 to 16);
signal S: mychararray(1 to 32);
The & operator is implicitly declared following the type declaration (a one dimensional array type).
See IEEE Std 1076-2008 6.4 Objects, 6.3 Subtype declarations, 5.3.2 Array types (mychararray is an unbounded array type) and 9.2.5 Adding operators (& concatenation operator).
The Mycharacters type is a scalar enumerated character type (discrete values), mychararray is an array type (elements, here the scalar type Mycharacters).
Renaud Pacalet asks about the use of the string type, your 36 value MyCharacters type requires 6 bit binary values to represent after synthesis, three quarters of the way to the std.STANDARD character type (requiring 8 bit binary values). On the other hand you can convert to ASCII values by adding the position value of a MyCharacters to "110000" (16#30# or 48, noting the 'LEFT index position of your array type is '0') if you include the :, ;, <, =, >, ?, and# characters before A:
30 0 31 1 32 2 33 3 34 4 35 5 36 6 37 7
38 8 39 9 3a : 3b ; 3c < 3d = 3e > 3f ?
40 # 41 A 42 B 43 C 44 D 45 E 46 F 47 G
48 H 49 I 4a J 4b K 4c L 4d M 4e N 4f O
50 P 51 Q 52 R 53 S 54 T 55 U 56 V 57 W
58 X 59 Y 5a Z
Instead of declaring type MyCharacters you could use type character with appropriate index constraints in your object declarations:
subtype MyCharacters is character('0' to 'Z');
type mychararray is array(natural range <>) of MyCharacters;
signal S1, S2: mychararray(1 to 8);
signal S3: mychararray(1 to 16);
signal S: mychararray(1 to 32);
Bundle that into a Minimal, Complete and Verifiable example:
entity mychar_concat is
end entity;
architecture foo of mychar_concat is
subtype MyCharacters is character range '0' to 'Z'; -- 16#30# to 16#5A#
type mychararray is array (natural range <>) of
character range '0' to 'Z';
signal S1: mychararray (1 to 8) := "01234567";
signal S2: mychararray (1 to 8) := "89:;<=>?";
signal S3: mychararray (1 to 16) := "#ABCDEFGHIJKLMNO";
signal S: mychararray (1 to 32);
function valuehex (inp: MyCharacters) return string is
variable retval: string (1 to 2);
variable hexval: integer;
variable remainder: integer;
begin
hexval := character'pos(inp) / 16;
retval(1) := character'val(hexval + 48); -- where '0' 'pos is 48.
-- expects inp is less than 'Z', (9 * 16 > 'Z')
remainder := character'pos(inp) rem 16;
if remainder < 10 then
retval(2) := character'val(remainder + 48); -- offset to '0'
else
retval(2) := character'val(remainder + 48 + 7); -- offset to 'A'
end if;
return retval;
end function;
begin
S <= S1 & S2 & S3; -- & implicity declared for mychararray
MONITOR:
process
begin
wait on S;
wait for 0 ns; -- skip "00000000000000000000000000000000" default S
report "S = " & string(S);
report "valuehex(MyCharacters'LEFT) = " &
valuehex(MyCharacters'LEFT) & "H";
report "valuehex(MyCharacters'RIGHT) = " &
valuehex(MyCharacters'RIGHT) & "H";
end process;
end architecture;
ghdl -r mychar_concat
mychar_concat.vhdl:37:9:#0ms:(report note): S = 0123456789:;<=>?#ABCDEFGHIJKLMNO
mychar_concat.vhdl:38:9:#0ms:(report note): valuehex(MyCharacters'LEFT) = 30H
mychar_concat.vhdl:40:9:#0ms:(report note): valuehex(MyCharacters'RIGHT) = 5AH
Where 30H is a '0' and 5AH is a 'Z'. Additionally see 16.2.2 Predefined attributes of types and objects.
We see that we derive 7 bit ASCII or 8 bit ISO/IEC 8859-1 character values (See 15.2 Character set) from MyCharacters values with little effort.
In either case the concatenation operators (array & array, element & array, array & element) are implicitly declared following the declaration of a single dimensional array type (mychararray here).
No, your array types cannot be declared as subtypes of MyCharacters, which is an enumerated type, not an array type.
Your 3 array types are different and independent types. The concatenation operator (&) is not defined on the combination of them that you use. You could overload it for this specific case but the simplest is probably be to use a common base type, that is, a parent unconstrained array type and declare subtypes of it with fixed ranges:
type mychararray is array(natural range <>) of MyCharacters;
subtype CharArray_8 is mychararray(1 to 8);
subtype CharArray_16 is mychararray(1 to 16);
subtype CharArray_32 is mychararray(1 to 32);
This way, they would all have the same base type and the implicit concatenation operator that is automatically declared with the mychararray type would work on any combination of them (assuming the size of the result is the same as the size of the variable it is assigned to, of course).
Note: I guess that you already know the string type (array of characters)?
I need a little help attempting to populate a matrix of size 3 by 5 with numbers read in from an external file in Ada programming.
The external file contains two rows of 15 digits:
1 3 8 4 10 2 4 38 43 4 8 12 32 16 6
23 8 9 9 18 41 11 21 12 2 1 6 33 11 22
Here's the code I have so far. I know that I can populate the array when reading from the file but I'm having trouble getting the syntax correctly. To be clear there are two matrices which need to be populated each 3x5 from the external file. Any help is greatly appreciated.
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;
procedure lab06 is
package Flt_IO is new Ada.Text_IO.Float_IO(FLOAT);
use Flt_IO;
MAX_ROW1 : constant := 3;
MAX_COL1 : constant := 5;
MAX_ROW2 : constant := 3;
MAX_COL2 : constant := 5;
n: NATURAL := 0;
I: INTEGER := 0;
type MATRIX_1 is array(INTEGER range 1..MAX_ROW1, INTEGER range 1..MAX_COL1) of INTEGER;
type MATRIX_2 is array(INTEGER range 1..MAX_ROW2, INTEGER range 1..MAX_COL2) of INTEGER;
First : MATRIX_1;
inf : FILE_TYPE;
begin
Open(inf, In_File, "lab06.in");
loop
exit when End_Of_File(inf);
Get(inf,n);
First(I) := n;
I := I + 1;
end loop;
Put(n);
Close(inf);
end Lab06;
Not really pretty, but here is a possible solution:
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Integer_Text_IO;
procedure lab06 is
MAX_ROW : constant := 3;
MAX_COL : constant := 5;
type MATRIX is array(NATURAL range 1..MAX_ROW, NATURAL range 1..MAX_COL) of NATURAL;
Inf : FILE_TYPE;
Matrix_1 : MATRIX;
Matrix_2 : MATRIX;
procedure PopulateMatrix(Inf : in FILE_TYPE; Result : out MATRIX) is
I: INTEGER := 0;
begin
loop
declare
N : NATURAL;
Row : Natural;
Column : Natural;
begin
Ada.Integer_Text_IO.Get(inf,N);
Column := (I rem MAX_COL) +1;
Row := (I - Column-1) / MAX_ROW +1;
Result(Row, Column) := N;
I := I + 1;
exit when I = MAX_ROW * MAX_COL;
end;
end loop;
end PopulateMatrix;
procedure PrintMatrix(Input : in MATRIX) is
begin
for Row in MATRIX'Range(1) loop
for Column in MATRIX'Range(2) loop
Ada.Integer_Text_IO.Put(Input(Row, Column));
end loop;
Put_Line("");
end loop;
end PrintMatrix;
begin
Open(Inf, In_File, "lab06.in");
PopulateMatrix(Inf, Matrix_1);
PopulateMatrix(Inf, Matrix_2);
Close(Inf);
PrintMatrix(Matrix_1);
Put_Line("");
PrintMatrix(Matrix_2);
end Lab06;
This gives you:
1 3 8 4 10
2 4 38 43 4
8 12 32 16 6
23 8 9 9 18
41 11 21 12 2
1 6 33 11 22
I hope this gets at least close to your expected output (which you have not really defined anywhere...).