Very simple example I am stuck with. I want design written in Verilog to return a year defined in source as 16-bit format to the outer world using two bytes.
`define MY_YEAR 16'd2017
then I need to somehow split this constant into two bytes to perform something like this
wire [7:0] w_year_byte = w_current_byte ? (`MY_YEAR >> 8) : (`MY_YEAR & 8'hff);
For me above expressions with MY_YEAR are not correct as their result is still 16-bit. And this statement does not compile at all…
I know how to do it with vectors, but have never done it before for constants; saw several answers for similar questions on the internet, but still unclear how to make things properly. May appear that my approach is totally wrong, will be extremely glad for educating me.
Update: my Verilog source is relatively big, and the main idea was to have this year definition at the very beginning of the source file, on the first line, because it will be changed frequently and I would not need to go down to find the value to change.
Reviewing Tom Carpenter's answer I realized I was making stupid mistake trying to declare parameter, local parameter or wire outside of the module (at the top of the source, before module declaration), so I follow his suggestion to have
`define MY_YEAR 16'd2017
on the first line of the source, and then somewhere after module declaration having
wire [15:0] c_MY_YEAR = `MY_YEAR;
and then using c_MY_YEAR[7:0]
and c_MY_YEAR[15:8]
as usual. Thanks Tom!
Best Answer
You're better off using
localparam
rather than'define
.For example:
Remember that with Verilog you are not working with computer programs, you aren't doing things in a procedural fashion, but rather describing hardware. If you want to access the MSB's or the LSB's, you can simply describe that - access them directly with the range selection operator (
[MSB:LSB]
) or part selection operator ([LSB+:WIDTH]
).Local parameters have the advantage over `defines in that they can be treated as constant wires - you can access the value of them in the same was as you would access the value of a wire.
Additionally you could easily change your
localparam
to aparameter
which would then allow you to change the value of the parameter when you instantiate the module - this is one of the building blocks of reusable parameterised modules. If your goal is to have the parameters at the top of the file, this can sort of be accomplished with Verilog 2001 ANSI style module declarations:If you have your heart set on a `define, you can access it by converting it to a wire. For example:
Once assigned to a wire you can then access it in the same way as the parameter version above: