I am writing a FSM in VHDL for a basic CPU control unit. In a process I use case statement to decode instruction code. My question is, does the order of the when "..." => statements matter/change anything, or will the inferred "circuit" be the same? I suspect it will, but I want to be sure.
I'd rather have the cases in order that is easy to orientate in, not ordered by value.
The order of the when "..." => statements cannot possibly matter/change anything in simulation or synthesis because in VHDL they must be mutually exclusive.
The order does not have any effect.
case State is
when A => ...
when B => ...
end case;
is identical to
case State is
when B => ...
when A => ...
end case;
I suppose some synthesis tools could produce different state encoding based on the order, but this should not be something that you should have to worry about.
There is no difference in your order because the synthesis tool will collect all branches of case statement and put them in one big multiplexer. The multiplexer will evaluate on your different branch conditions (obviously your inputs).
Don't forget when others => statement ;)
More information about "case statement":
http://www.vhdl-online.de/courses/system_design/vhdl_language_and_syntax/sequential_statements/case_statement
Related
I mostly use TypeScript during my work day and when applying functional patterns I oftentimes see a pattern like:
const someArray = anotherArray.filter(filterFn).map(transformFn)
This code will filter through all of anotherArray's items and then go over the filtered list (which may be identical if no items are filtered) again and map things. In other words, we iterate over the array twice.
This behavior could be achieved with a "single pass" over the array with a reduce:
const someArray = anotherArray.reduce((acc, item) => {
if (filterFn(item) === false) {
return acc;
}
acc.push(item);
return acc;
}, [])
I was wondering if such optimization is something the transpiler (in the TS world) knows to do automatically and whether such optimizations are automatically done in more "functional-first" languages such as Clojure or Haskell. For example, I know that functional languages usually do optimizations with tail recursion, so I was wondering also about the "filter then map" case. Is this something that compilers actually do?
First of all, you usually shouldn't obsess about getting everything into a single pass. On small containers there is not that much difference between running a single-operation loop twice and running a dual-operation loop once. Aim to write code that's easily understandable. One for loop might be more readable than two, but a reduce is not more readable than a filter then map.
What the compiler does depends on your "container." When your loop is big enough to care about execution time, it's usually also big enough to care about memory consumption. So filtering then mapping on something like an observable works on one element at a time, all the way through the pipeline, before processing the next element. This means you only need memory for one element, even though your observable could be infinite.
I am trying to write a predicate that ‘exists’ inside the ‘scope’ of another predicate . The reason I need this is because both predicates make use of the same very large parameters/arrays and the predicate I want to nest is doing self recurssion many times , so I want to avoid copying the same parameters . So , is there any way i can do this in Swi-Prolg ?
Thanks in advance .
You don't need to. You have to realize that all the terms "named" by Prolog variable names are already global, although inaccessible when the clause doesn't have a name referencing them (and names are always local to a clause). That "very large array" is on the heap. Just pass the name to it to any other predicate at ~0 cost.
As Paulo Moura says.
Suppose you have:
foo(BigArray) :- do_things(BigArray),do_more_things(BigArray).
Suppose do_things/1 either just prints the element at position 0 if it is an instantiated term, or sets it to bar if its is a fresh term:
do_things(BigArray) :- nth0(0,BigArray,Elem),nonvar(Elem),!,write(Elem).
do_things(BigArray) :- nth0(0,BigArray,Elem),var(Elem),!,Elem=bar.
If there was a fresh term on position 0, the, on return to foo/1, the atom bar on position 0 is visible to the caller and to do_more_things/1 because that list designated by BigArray is a "global term".
Some precision on your other question on whether to use "global variables":
SWI-Prolog also has "Global Variables", which are apparently similar to the GNU Prolog "Global Variables":
Global Variables
We read:
Global variables are associations between names (atoms) and terms.
They differ in various ways from storing information using assert/1 or
recorda/3.
...which means that their purpose is similar to the purpose of assert/1 and recorda/3: Storing state that survives query termination at the Prolog toplevel - similar to how program clauses of a program are stored.
I would say, use those only if absolutely needed.
Also read the intro: Database, where we find:
The recorded database is not part of the ISO standard but fairly
widely supported, notably in implementations building on the‘Edinburgh
tradition'. There are few reasons to use this database in SWI-Prolog
due to the good performance of dynamic predicates.
Having just discovered alignment issues for the first time I am unsure on which method is the best/safest way to deal with them. I have a record which I am serialising to send over a Stream and vice-versa so it must meet the interface spec and contain no padding.
Given the example record:
type MyRecord is record
a : Unsigned_8;
b : Unsigned_32;
end record;
This by default would require 8 bytes but I am able to remove packing using 2 methods:
for MyRecord'Alignment use 1;
or
pragma Pack (MyRecord);
I have found a few questions relating to C examples but haven't been able to find a clear answer on which method is the most appropriate, how to determine which method to use or if they are equivalent?
UPDATE
When I tried both on my 'real' code rather than a basic example I found that the Alignment attribute achieved what I was looking for. pragma Pack significantly reduced the size, not confirmed but I assume it has packed the many enumerated types I'm using, overriding the 'Size use 8 attribute applied to each type.
For Streams you could leave MyRecord without any representation clauses and use the default MyRecord’Write and MyRecord’Read; ARM 13.13.2(9) says
For elementary types, Read reads (and Write writes) the number of stream elements implied by the Stream_Size for the type T; the representation of those stream elements is implementation defined. For composite types, the Write or Read attribute for each component is called in canonical order, which is last dimension varying fastest for an array (unless the convention of the array is Fortran, in which case it is first dimension varying fastest), and positional aggregate order for a record.
One possible disadvantage of the GNAT implementation (and maybe of others) is that the ’Write and ’Read calls each end in a call to the underlying network software. Not a problem (aside from possible inefficiency) normally, but if you’re using TCP_NODELAY (or worse, UDP) this is not the behaviour you’re looking for.
Overloading ’Write leads back to your original problem (but at least it’s confined to the overloading procedure, so the rest of your program can deal with properly aligned data).
I’ve used an in-memory stream for this (especially the UDP case); ’Write to the in-memory stream, then send the Stream_Element_Array to the socket. One example is ColdFrame.Memory_Streams (.ads, .adb).
I think you want the record representation clauses, if you want full control:
for MyRecord'Size use 40;
for MyRecord use record
a at 0 range 0 .. 7;
b at 1 range 0 .. 31;
end record;
(or some such, I might have messed up some of the indices here).
NB: edited as per comment by Simon
I need some advice on how to design an asynchronous FIFO. I understand the meta stability issue when capturing data into a different clock domain, my question is how does using a two flip flop shift register assist in synchronization of write pointer and read pointer values for full and empty flag calculation.
When register captures a data of a different domain there is a possibility it can enter a metastable state and can settle to a unknown value, so how do u effectively resolve this issue.
Thanks
Your read and write pointers need to use gray encoding when transferred from one clock domain to the other. As you should know, only 1 bit of a gray counter is different between two consecutive values. Thus, metastability can affect only the one changing bit. After re-synchronization, the transferred pointer will be either the updated pointer or its previous value.
In either case, this is not a problem and only lead to pessimistic flags/count for your FIFO.
I use regular counter for my read/write pointer, and use the following functions to convert them to gray code. They are in VHDL, but you should get the idea:
function bin_to_gray(a: unsigned) return unsigned is
begin
return a xor ('0' & a(a'left downto 1));
end function bin_to_gray;
function gray_to_bin(a: unsigned) return unsigned is
variable ret : unsigned(a'range);
begin
ret(a'left) := a(a'left);
for i in a'left-1 downto 0 loop
ret(i) := ret(i+1) xor a(i);
end loop;
return ret;
end function gray_to_bin;
Jonathan explained it well.
I would just like to add a few points:
First, in addition to your 2-stage synchronizer registers you must also have a source register.
You can never feed signals from combinational logic into your 2-stage synchronizer, since combinational logic produce glitches.
You must also be aware that Verilog and VHDL has no built-in support for clock domain crossings and metastability.
Even if you create a proper 2-stage synchronizer to transfer the gray coded pointers, there is no guarantee that the synthesis tool does not change your synchronizers in a way which make it ineffective in protecting againsts metastability. Some synthesis tools try to detect synchronizers and leave them alone. Some don't. And in either case, you should not rely on it.
For a completely proper clock domain crossing, you must constrain the synchronizer and the source register using vendor-specific attributes and SDC timing constraints.
I've been trying to write a Finite State Machine in VHDL code for a simple 16-bit processor I'm implementing on an Altera DE1 board. In the Finite State Machine, I have a CASE statement that handles the different 16-bit instructions, which are brought into the FSM by a 16-bit STD_LOGIC_VECTOR. However, I'm having a little trouble in the decode state where the Finite State Machine decodes the instruction. One of the instructions is an ADD which takes two registers as operands and a third as the destination register. However, I also have an ADD instruction which takes a register and a 5-bit immediate value as operands and a second register for the destination. My problem is that in the CASE statement, I need to be able to differentiate between the two different ADD instructions. So, I thought that if I use wildcard values like "-" or "X" in the CASE statement, I would be able to differentiate between the two with just two cases instead of listing all of the possible register/immediate value combinations. For example:
CASE IR IS --(IR stands for "Instruction Register")
WHEN "0001------0-----" => (Go to 3-register add);
WHEN "0001------1-----" => (Go to 2-register/immediate value add);
WHEN OTHERS => (Do whatever);
END CASE;
These aren't the only two instructions I have, I just put these two to make this post a little shorter. When I compile and run this code, the processor stops executing when it gets to the "decode" state. Also, Quartus gives many, many warnings saying things like "VHDL choice warning at LC3FSM.vhd(37): ignored choice containing meta-value ""0001------0-----"""
I am at a loss as to how to go about accomplishing this. I REALLY do not and probably don't need to define every single 16-bit combination, and I hope there's a way to use wildcards in a STD_LOGIC_VECTOR to minimize the number of combinations I will have to define.
Does anybody know how to accomplish this?
Thanks
That can't be done unfortunately. Rather unexpectedly for most users, the comparison operator = and the case comparison perform a literal comparison. This is because the std_logic type is just a set of characters, which happen to perform like logic values due to the way other functions (eg and and or) are defined.
VHDL-2008 introduces a new case statement case? which performs as you expect - you'll need to tell your compiler to operate in VHDL 2008 mode. In addition, there is a ?= operator in VHDL 2008 which compares two values, taking account of -s.
If you are lumbered with a compiler which still doesn't support VHDL 2008, complain to the supplier. There is also a std_match function allows you to perform comparisons in older VHDL revisions, but nothing that I am aware to make the case statement work that way.
Assuming you don't need the other bits in the instruction you could hack your way around this by masking the other bits with a pre-check process. (Or just ensure the other bits are reset when you write the instruction?)
This really is a bit of a hack.
assuming IR is stored as a variable
if IR(15 downto 12) == "0001" then
IR := IR_in(15 downto 12) & "0000000" & IR_in(5) & "00000";
else
IR := IR_in
end if;
CASE IR IS --(IR stands for "Instruction Register")
WHEN "0001000000000000" => (Go to 3-register add);
WHEN "0001000000100000" => (Go to 2-register/immediate value add);
WHEN OTHERS => (Do whatever);
END CASE;
Alternatively assuming your instruction is cleverly thought out (are the first four bits the command word or something along those lines?) you could do nested case statements and do the differentiation as needed in those sub blocks.