VHDL equivalent for always @(*)

L

lb.edc

Hi,

I'm translating a piece of Verilog code to VHDL:

Here's the code:
always @ () begin
// default value
reg_dataout <= 8'h00;

if (sciaddress == 11'h620) begin
reg_dataout <= 8'hAA;
end

if (sciaddress == 11'h621) begin
reg_dataout <= 8'h55;
end
if (sciaddress == 11'h622) begin
reg_dataout <= creg;
end
end

Does this translate to?
process (rst)
begin
if reset = '1' then
reg_dataout <= (others => '0');
else
if sciaddress = "11000100000" then
:
:
:
any help is appreciated.

Luc
 
P

Paul Uiterlinden

Hi,

I'm translating a piece of Verilog code to VHDL:

Here's the code:
always @ () begin
// default value
reg_dataout <= 8'h00;

if (sciaddress == 11'h620) begin
reg_dataout <= 8'hAA;
end

if (sciaddress == 11'h621) begin
reg_dataout <= 8'h55;
end
if (sciaddress == 11'h622) begin
reg_dataout <= creg;
end
end

Does this translate to?
process (rst)
begin
if reset = '1' then
reg_dataout <= (others => '0');
else
if sciaddress = "11000100000" then
:
:
:
any help is appreciated.

Luc

I'm no hero with Verilog, but I would say:

process(sciaddress, creg) is
begin
-- default value
reg_dataout <= X"00";

if sciaddress = B"110_0010_0000" then
reg_dataout <= X"AA";
end if;

if sciaddress = B"110_0010_0001" then
reg_dataout <= 8'h55;
end if;

if sciaddress = B"110_0010_0010" then
reg_dataout <= creg;
end if;
end process;

In VHDL you cannot (yet) specify hex literals for lengths that are no
multiple of four. That's why I used binary literals for comparison with
sciaddress.

In stead of the ifs (or if-elsifs-else) you can use a case statement:

process(sciaddress, creg) is
begin
case sciaddress is
when B"110_0010_0000" =>
reg_dataout <= X"AA";
when B"110_0010_0001" =>
reg_dataout <= X"55";
when B"110_0010_0010" =>
reg_dataout <= creg;
when others =>
reg_dataout <= X"00";
end case;
end process;

And you can do away with the whole process by using a selected signal
assignment statement:

with sciaddress select reg_dataout <=
X"AA" when B"110_0010_0000",
X"55" when B"110_0010_0001",
creg when B"110_0010_0010",
X"00" when others;

Who said VHDL is more verbose than Verilog? ;-)
 
A

Andy

I'm no hero with Verilog, but I would say:

process(sciaddress, creg) is
begin
-- default value
reg_dataout <= X"00";

if sciaddress = B"110_0010_0000" then
reg_dataout <= X"AA";
end if;

if sciaddress = B"110_0010_0001" then
reg_dataout <= 8'h55;
end if;

if sciaddress = B"110_0010_0010" then
reg_dataout <= creg;
end if;
end process;

In VHDL you cannot (yet) specify hex literals for lengths that are no
multiple of four. That's why I used binary literals for comparison with
sciaddress.

In stead of the ifs (or if-elsifs-else) you can use a case statement:

process(sciaddress, creg) is
begin
case sciaddress is
when B"110_0010_0000" =>
reg_dataout <= X"AA";
when B"110_0010_0001" =>
reg_dataout <= X"55";
when B"110_0010_0010" =>
reg_dataout <= creg;
when others =>
reg_dataout <= X"00";
end case;
end process;

And you can do away with the whole process by using a selected signal
assignment statement:

with sciaddress select reg_dataout <=
X"AA" when B"110_0010_0000",
X"55" when B"110_0010_0001",
creg when B"110_0010_0010",
X"00" when others;

Who said VHDL is more verbose than Verilog? ;-)

I wasn't aware that '_' was allowed in hex string literals... learn
something new every day.

If you make sciaddress an unsigned, then you can compare to a
hexadecimal integer literal:

if sciaddress = 16#620# then

You could also define sciaddress as an integer, and even use hex
integer literals as case targets.

Andy
 
P

Paul Uiterlinden

Andy said:
I wasn't aware that '_' was allowed in hex string literals... learn
something new every day.

To be precise: they are called bit string literals and they can be specified
in binary, octal and hexdecimal form:

B"111_0010"
O"377_001"
X"AA_BB_CC"

And yes: using the binary form of bit string literals has the benefit over a
string literal to allow underscores. It improves readability.

Of course the best improvement of readability would be creating constants
with decent names!
If you make sciaddress an unsigned, then you can compare to a
hexadecimal integer literal:

if sciaddress = 16#620# then

You could also define sciaddress as an integer, and even use hex
integer literals as case targets.

Yes indeed.
 
K

Kai Harrekilde-Petersen

Paul Uiterlinden said:
To be precise: they are called bit string literals and they can be specified
in binary, octal and hexdecimal form:

B"111_0010"
O"377_001"
X"AA_BB_CC"

And yes: using the binary form of bit string literals has the benefit over a
string literal to allow underscores. It improves readability.

Of course the best improvement of readability would be creating constants
with decent names!

You could also do
if sciaddress = conv_std_logic_vector(16#620#,16) then ...
but the conv_std_logic lowers the readability.

At my previous work we had a need for comparing std_logic_vectors to
numbers quite often, so we defined a function named to_slv(value,nbits)
which would call conv_std_logic_vector to do it's work (we had a bunch
of others, like to_bool(), to_int(), to_nat(), to_sl(), etc - you get
the drift).

This removed quite a bit of VHDL's uglyness and improved readability
significantly.


Kai
 
L

lb.edc

Paul,

Thanks for your input. If I understand this correct, the Verilog code
could also translate to a concurrent statement in the form:
reg_dataout <= X"AA" when sciaddress = B"110_0010_0000" else
X"55" when sciaddress = B"110_0010_0001" else
creg when sciaddress = B"110_0010_0010" else
X"00"

Thus not using any process. Correct? Or is there a difference?

Luc
 
A

Andy

Luc,

The difference between:

with sciaddress select reg_dataout <=
X"AA" when B"110_0010_0000",
X"55" when B"110_0010_0001",
creg when B"110_0010_0010",
X"00" when others;

and:

reg_dataout <= X"AA" when sciaddress = B"110_0010_0000" else
X"55" when sciaddress = B"110_0010_0001" else
creg when sciaddress = B"110_0010_0010" else
X"00"

Is that in the former, the compiler ensures that all conditions are
mutually exclusive (meaning there is no priority), and completely
specified (all values of sciaddress are accounted for). In the
latter, the conditions can be anything, could overlap, could be
incomplete, and priority is assumed. The former is analogous to a case
statement in a process, and the latter is analogous to an if-then
statement. You are correct that both would result in the same behavior
when simulated, and likely the same circuit when synthesized.

To say that either is done without a process is only half correct.
Both are concurrent assignment statements, which are implied
processes.

Andy
 
P

Paul Uiterlinden

Paul,

Thanks for your input. If I understand this correct, the Verilog code
could also translate to a concurrent statement in the form:
reg_dataout <= X"AA" when sciaddress = B"110_0010_0000" else
X"55" when sciaddress = B"110_0010_0001" else
creg when sciaddress = B"110_0010_0010" else
X"00"

Thus not using any process. Correct? Or is there a difference?

As Andy pointed out, there is no real functional difference. Thank you Andy
for the elaboration.
 
B

Brian Drummond

I'm no hero with Verilog, but I would say:

process(sciaddress, creg) is
begin
-- default value
reg_dataout <= X"00";

if sciaddress = B"110_0010_0000" then
In VHDL you cannot (yet) specify hex literals for lengths that are no
multiple of four. That's why I used binary literals for comparison with
sciaddress.

Sometimes an intermediate level of ugliness involving concatenation of a
binary and a hex literal may be more readable...

reg_dataout <= X"AA" when sciaddress = B"110" & X"20" else

constant Six : std_logic_vector (2 downto 0) := B"110";

reg_dataout <= X"AA" when sciaddress = Six & X"20" else
X"55" when sciaddress = Six & X"21" else
creg when sciaddress = Six & X"22" else
X"00";

- Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top