Electrical – Truncate and other operations on the constant in Verilog


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:

module blah (


localparam MY_YEAR = 16'd2017; //This is a local parameter which cannot be seen or changed outside the module

wire [7:0] w_year_byte = w_current_byte ? MY_YEAR[15:8] : MY_YEAR[7:0];



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 a parameter 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:

module blah #(
    parameter MY_YEAR = 16'd2017
    input whatever,
    output bob,
    input cheese

If you have your heart set on a `define, you can access it by converting it to a wire. For example:

wire [15:0] my_year_wire = `MY_YEAR;

Once assigned to a wire you can then access it in the same way as the parameter version above:

wire [7:0] w_year_byte = w_current_byte ? my_year_wire[15:8] : my_year_wire[7:0];