response <= NOT_IMPLEMENTED;
if VARIANT = THIS_ONE then
Decoder_THISONE : case token is
when CMD_XYZ =>
params.XYZ <= argument;
response <= HANDLED;
when ... =>
...
when others =>
end case;
end if;
if VARIANT = OTHER_ONE then
Decoder_OTHER_ONE : case token is
when CMD_SOMETHING =>
...
response <= HANDLED;
when ... =>
...
when others =>
end case;
end if;
Actually you can but you'd use a plain if instead of #ifdef. You basically insist on using #ifdef while there is a VHDL language construct (namely the 'if statement') that does exactly the same from a functional point of view when the condition is based on a constant. The OP's question however seems to be how to create nicer looking code that isn't littered with a whole bunch of ifs and #ifdef doesn't make things any nicer. Take note of SiliconWizzards remark about how and why a synthesizer is already doing the same as the C pre-processor. VHDL code that is never used, is optimised away so why insist on adding an extra layer to the language that does the same?
In synthesizable code, functions and procedures in VHDL can only be evaluated at compile time - thus when properly used, they give fancy preprocessing features.That might be a bad use of the term "evaluated", since both functions and processes are synthesiseable and used to produce complex combinatorial results (the majority of ieee packages are functions alongside operator overrides which are functions themselves). So they are most certainly evaluated at runtime.Nope nope. This was a carefully choosen term here.
You show a misconception of what functions and procedures are in VHDL, or you just didn't understand or even read what I wrote. When synthesized, they can ONLY be evaluated at compile-time. They always yield static logic structures that reflect their behavior. That's why, for synthesis, they act as preprocessing and nothing else.
Static is a strictly defined term in VHDL (the language) so you cant just redefine and reuse it how you like. Evaluated is not strictly defined but most people would understand it to mean the inputs are parsed to produce the output. Elaboration is probably where you were headed, but your refining/misunderstanding of terms makes your contributions incoherent.
Let's not uselessly pollute this thread please.
[barely coherent waffle]
Point is, again, (was it really not clear?) that functions and procedures in the context of synthesis are nothing but fancy preprocessing - which was the whole point all along.
In synthesizable code, functions and procedures in VHDL can only be evaluated at compile time - thus when properly used, they give fancy preprocessing features.
Will it result in the unpossible command selectors being optimized away? There's only one way to find out: code it and synthesize it, which will be project for tomorrow.
type VARIANT_TYPE is (E_ALL,E_VAR1,E_VAR2,E_TEST);
constant THIS_VARIANT : VARIANT_TYPE := E_VAR2;
type STATE_TYPE is (S_BLEEP,S_BLOOP,S_NUREEK,S_HERUNGER,S_ROATUT,S_UNIMPLEMENTED);
signal command : STATE_TYPE;
constant VARIANT_WIDTH : INTEGER := integer(ceil(log2(real(VARIANT_TYPE'pos(VARIANT_TYPE'high)+1))));
constant STATE_WIDTH : INTEGER := integer(ceil(log2(real( STATE_TYPE'pos( STATE_TYPE'high)+1))));
function state_encode(
variant : in VARIANT_TYPE;
state : in STATE_TYPE)
return STD_LOGIC_VECTOR is
variable encoded : STD_LOGIC_VECTOR (VARIANT_WIDTH+STATE_WIDTH-1 downto 0);
begin
encoded := std_logic_vector(to_unsigned(VARIANT_TYPE'pos(variant), VARIANT_WIDTH) & to_unsigned(STATE_TYPE'pos(state), STATE_WIDTH));
if variant = E_ALL then
encoded(encoded'high downto encoded'high+1-VARIANT_WIDTH) := (others => '-');
end if;
return encoded;
end function;
begin
process(all)
begin
if rising_edge(clock) then
case state_encode(THIS_VARIANT,command) is
when state_encode(E_ALL,S_BLEEP) =>
params.bleep <= arguement;
response <= R_OK;
when state_encode(E_VAR1,S_BLOOP) |
state_encode(E_VAR2,S_BLOOP) =>
params.bloop <= arguement;
response <= R_OK;
when state_encode(E_VAR1,S_NUREEK) =>
params.nureek <= arguement;
response <= R_OK;
when state_encode(E_VAR1,S_ROATUT) =>
params.roatut <= arguement;
response <= R_OK;
when state_encode(E_TEST,S_HERUNGER) =>
response <= R_OK;
when others =>
response <= R_UNIMPLEMENTED;
end case;
end if;
end process;
The problem the OP has is a code structuring one. First thing that needs to be done is for the command handling part to always support all commands (so the enumeration needs to be complete with all commands). Secondly a layer (translation table, function, whatever) needs to go between the input and command processing. That layer uses the variant type to check if a certain command is supported or not. This likely takes some restructuring of the code but that advantage is that determining which commands are supported by what type is in 1 location. This will help to keep code maintainable.
The problem the OP has is a code structuring one. First thing that needs to be done is for the command handling part to always support all commands (so the enumeration needs to be complete with all commands). Secondly a layer (translation table, function, whatever) needs to go between the input and command processing. That layer uses the variant type to check if a certain command is supported or not. This likely takes some restructuring of the code but that advantage is that determining which commands are supported by what type is in 1 location. This will help to keep code maintainable.That's more useless talk. Show us the code already!
Stop trolling and do your own homework. Maybe you can add something useful to this thread instead of trying to bait people into yet another VHDL versus systemVerilog thread. The OP uses VHDL and needs a solution that is written using VHDL.
LOL you guys as always went deep into the woods in your attempts to defend that POS of a language As I understood, what OP wants is this (code in C so that even VHDLers would understand):Code: [Select]switch (op)
Important point is that OP_EXTENDED_x opcodes are treated as unknown ones if such support is disabled. Now please show us how to implement this trivial code. And no, a bunch of generate's with copy-pasted switched for all possible permutations of supported opcodes is not acceptable.
{
case OP_FOO:
//handing operation FOO
break;
case OP_BAR:
//handing operation BAR
break;
#ifdef OP_EXTENDED_1_SUPPORTED
case OP_EXTENDED_1:
//handing operation OP_EXTENDED_1
break;
#endif
#ifdef OP_EXTENDED_2_SUPPORTED
case OP_EXTENDED_2:
//handing operation OP_EXTENDED_2
break;
#endif
default:
//handing unknown operation
break;
}
So yes, "use SystemVerilog" is the only sureway solution to avoid having to deal with this garbage again.
The 'generate' statement is the way to get this kind of things done.
One way: make a component for the body of each case statement. That component's contents can have a generate statement that creates output based on what is being generated. There is zero code replication. In fact, closely related functions can be implemented using the same component.
One way: make a component for the body of each case statement. That component's contents can have a generate statement that creates output based on what is being generated. There is zero code replication. In fact, closely related functions can be implemented using the same component.
You can't instantiate an entity within a process.
It's the same problem as trying to put a generate within a process.
Well, despite being a VHDL partisan with an allergy to all things Verilog, I will state that what asmi writes above is exactly what I want.
And that still won't make me switch to SystemVeriilog.
Well, despite being a VHDL partisan with an allergy to all things Verilog, I will state that what asmi writes above is exactly what I want.
And that still won't make me switch to SystemVeriilog.In my experience people use VHDL because they are too old/too lazy/too stubborn to learn SystemVerilog. I'm yet to meet a person who learned both languages and voluntarily chose VHDL over SV.
So I'll hazard a guess that all these "allergies" are just a lousy coverup for good old laziness.
Well, in Europe VHDL is used because it is the language that most companies ask for in their job offers. Therefore, it is the language that universities usually teach in their EE degrees. Consequently, it is better to focus your efforts on learning about dynamic reconfiguration of FPGAs, reliability, IC design, etc. than learning another language
Well, in Europe VHDL is used because it is the language that most companies ask for in their job offers. Therefore, it is the language that universities usually teach in their EE degrees. Consequently, it is better to focus your efforts on learning about dynamic reconfiguration of FPGAs, reliability, IC design, etc. than learning another languageYou still got to learn both at least to some degree because chances are you are going to have to work with third-party IPs written in another language. So you can only really ignore other languages if you are a hobbyist and can afford to roll your own, in professional setting you will have to deal with both.
But I was talking about personal choice given both options are on the table. I've never met a VDHL person who also knows SystemVerilog well, but I've met a plenty of SV people which also know VHDL.
Maybe it is something related to the type of applications that they design, but the companies for which I have worked for didn’t allow us to use any IP programmed in a different language to VHDL
Well, despite being a VHDL partisan with an allergy to all things Verilog, I will state that what asmi writes above is exactly what I want.
And that still won't make me switch to SystemVeriilog.In my experience people use VHDL because they are too old/too lazy/too stubborn to learn SystemVerilog. I'm yet to meet a person who learned both languages and voluntarily chose VHDL over SV.
So I'll hazard a guess that all these "allergies" are just a lousy coverup for good old laziness.
LOL you guys as always went deep into the woods in your attempts to defend that POS of a language As I understood, what OP wants is this (code in C so that even VHDLers would understand):Code: [Select]switch (op)
Important point is that OP_EXTENDED_x opcodes are treated as unknown ones if such support is disabled. Now please show us how to implement this trivial code. And no, a bunch of generate's with copy-pasted switched for all possible permutations of supported opcodes is not acceptable.
{
case OP_FOO:
//handing operation FOO
break;
case OP_BAR:
//handing operation BAR
break;
#ifdef OP_EXTENDED_1_SUPPORTED
case OP_EXTENDED_1:
//handing operation OP_EXTENDED_1
break;
#endif
#ifdef OP_EXTENDED_2_SUPPORTED
case OP_EXTENDED_2:
//handing operation OP_EXTENDED_2
break;
#endif
default:
//handing unknown operation
break;
}
So yes, "use SystemVerilog" is the only sureway solution to avoid having to deal with this garbage again.
Well, despite being a VHDL partisan with an allergy to all things Verilog, I will state that what asmi writes above is exactly what I want.