Author Topic: VHDL: How can I truncate a hex constant to match a smaller vector?  (Read 9798 times)

0 Members and 1 Guest are viewing this topic.

Offline DongulusTopic starter

  • Regular Contributor
  • *
  • Posts: 232
  • Country: us
I'm having some trouble assigning constant hex values to vectors of a smaller size. In my current project, I am using a FPGA to receive 7-bit ASCII characters from a terminal emulator application on a PC. I need to compare and assign 7-bit logic vectors with hard coded values that are most easily read as two digit hex, e.g. 0x0D.

In VHDL, I want to make this sort of assignment or compare:
Code: [Select]
signal AsciiChar : std_logic_vector(6 downto 0) := x"0D";
....
if (AsciiChar = x"0D") then ...
But assigning or comparing an 8-bit value with a 7-bit vector gives me mis-match errors.

For anyone familiar with Verilog, this operation is trivial,
Code: [Select]
CR = 7'h0D;but VHDL doesn't seem to easily offer the same sort of function for the case of assigning a truncated hex value. Does anyone know of some easy way to do this?

By the way, I found the function named "align_size" in the "std_logic_arith" package that seems like should work, but Quartus keeps giving me an error that the function isn't defined, even though I have the std_logic_arith package declared.  :-//
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #1 on: March 17, 2014, 04:53:45 pm »
How about specifying the length of that hex literal, like so:

Code: [Select]
signal AsciiChar : std_logic_vector(6 downto 0) := x"0D";
....
if (AsciiChar = 7x"0D") then ...

Edit: Looks like this feature was added in VHDL-2008. Also check this one: http://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/#bistring
« Last Edit: March 17, 2014, 05:03:19 pm by mrflibble »
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13804
  • Country: gb
    • Mike's Electric Stuff
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #2 on: March 17, 2014, 05:03:53 pm »
You could just make the signal 8 bits wide and tie the top bit low - it will get optimised out.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #3 on: March 17, 2014, 05:37:29 pm »
You could just make the signal 8 bits wide and tie the top bit low - it will get optimised out.
You could, but that's rather nasty and will mess up your modules real quick. Especially if this 7-bit signal comes from another module. If you want to go that route the sortof doable way is to keep the signal 7-bits, then extend to 8-bits right at the comparison operator. As in concatenate with a 0 MSB, and compare that to the 8-bit literal. At least that way you can see wtf is going on. Or maybe you meant this...

But with a bit of luck Dongulus' tools support VHDL-2008, then it's problem solved in the exact same way as it is for verilog.
 

Offline FrankBuss

  • Supporter
  • ****
  • Posts: 2366
  • Country: de
    • Frank Buss
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #4 on: March 17, 2014, 06:52:52 pm »
Use hex integer literals and to_unsigned to convert it to a vector of the required length, then std_logic_vector to convert it, if you don't use unsigned:

Code: [Select]
if AsciiChar = std_logic_vector(to_unsigned(16#0D#, 7)) then

To make it more readable, you could create a subtype and a function:

Code: [Select]
foo: process(AsciiChar) is
subtype AsciiType is std_logic_vector(6 downto 0);

function b7(v: integer) return AsciiType is
begin
return AsciiType(to_unsigned(v, AsciiType'Length));
end function;

begin
if AsciiChar = b7(16#0D#) then
   ...
end if;
end process;
So Long, and Thanks for All the Fish
Electronics, hiking, retro-computing, electronic music etc.: https://www.youtube.com/c/FrankBussProgrammer
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #5 on: March 17, 2014, 07:19:21 pm »
...  but Quartus keeps giving me an error that the function isn't defined, even though I have the std_logic_arith package declared.  :-//


The Quartus II software contains support for VHDL 2008 with the following constructs defined in the IEEE Std 1076-2008 version of the IEEE Standard VHDL Language Reference Manual:

...

Section 15.8—Enhanced Bit-string literals

Code: [Select]
if (AsciiChar = 7x"0D") then ...
Problem solved?  :-//

note the 7 :P
 

Offline DongulusTopic starter

  • Regular Contributor
  • *
  • Posts: 232
  • Country: us
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #6 on: March 17, 2014, 08:01:04 pm »
To make it more readable, you could create a subtype and a function
You are right FrankBuss, for this case a subtype will be useful. Luckily, looking further I found that the work has been already done for me because the standard VHDL package already includes an enumerated "character" type. In fact, now I won't even need to assign or compare signals with hex values because I can use character literals instead (now I don't need to look up ASCII tables either  :)).

Still, for future reference I want to find a good solution for the general case.

Use hex integer literals and to_unsigned to convert it to a vector of the required length, then std_logic_vector to convert it, if you don't use unsigned:

Code: [Select]
if AsciiChar = std_logic_vector(to_unsigned(16#0D#, 7)) then

Yes, I got the above statement to work. It's definitely not pretty, but at least I know I have a working solution. As you have stated I could always write a function to make it more readable if the design warrants it.

But with a bit of luck Dongulus' tools support VHDL-2008, then it's problem solved in the exact same way as it is for verilog.

I'm really hesitant to adopt the 2008 standard. I would maybe consider it for a personal project, but this design isn't and I'm most likely required to use the 1993 standard.

You could just make the signal 8 bits wide and tie the top bit low - it will get optimised out.

Yeah, good idea. I had decided to do this before I found out that the character type existed. Not something I would want to do in most other cases of awkward vector lengths though.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #7 on: March 17, 2014, 08:28:34 pm »
But with a bit of luck Dongulus' tools support VHDL-2008, then it's problem solved in the exact same way as it is for verilog.

I'm really hesitant to adopt the 2008 standard. I would maybe consider it for a personal project, but this design isn't and I'm most likely required to use the 1993 standard.
Fair point. In that case FrankBuss' solution using a function to cast and then compare looks to be the cleanest option for the general case.
 

Offline marshallh

  • Supporter
  • ****
  • Posts: 1462
  • Country: us
    • retroactive
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #8 on: March 17, 2014, 08:32:51 pm »
Use verilog and abuse bit widths with impunity and at your own risk  :-/O
Verilog tips
BGA soldering intro

11:37 <@ktemkin> c4757p: marshall has transcended communications media
11:37 <@ktemkin> He speaks protocols directly.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #9 on: March 17, 2014, 09:24:00 pm »
Use verilog and abuse bit widths with impunity and at your own risk  :-/O
Or my personal favorite, make a hard to spot typo in one of your signal names. And then the tools will happily assume that of course you meant that, and will whip up a new set of wires for you. Which will then result in all sorts of fun!  ;D Fell for that one a few times. I've been using `default nettype none ever since, to prevent that particular headache.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: VHDL: How can I truncate a hex constant to match a smaller vector?
« Reply #10 on: March 18, 2014, 02:34:32 am »
Only thing that comes to mind other than VHDL 2008 is to mix binary with hex by using the & concatenation.
 
Code: [Select]
signal AsciiChar : std_logic_vector(6 downto 0) := "000" & x"D";
....
if (AsciiChar = ("000" & x"D")) then ...

Or use binary only, less pretty and more confusing
Code: [Select]
signal AsciiChar : std_logic_vector(6 downto 0) := "0001101";
....
if (AsciiChar = "0001101") then ...

Or better yet, since you need 7 bits, concatenate octal and hex
Code: [Select]
signal AsciiChar : std_logic_vector(6 downto 0) := o"0" & x"D";
....
if (AsciiChar = (o"0" & x"D")) then ...
« Last Edit: March 18, 2014, 02:41:00 am by miguelvp »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf