bit selects, macros, and parameters (oh my)

  • Thread starter unfrostedpoptart
  • Start date
U

unfrostedpoptart

Guest
Hi all.

I'd like some help/opinions from the group. I've got a design that
uses parameters as constants for register/memory addresses, e.g.
parameter ADDR1 = 24'h10_0000;
parameter ADDR2 = 24'h10_0010;

Since these are used globally, in many synthesizable blocks and
testbench files, I'd rather use macros/`defines so that each module
doesn't have to include the parameter file inside the module. However,
I've got a catch: in many places I need to use a slice of the
constant, e.g.:

if (XXX[23:10] == ADDR1[23:10]) ....

and this won't work if I use a macro (e.g. `define ADDR1 24'h10_0000).
Some of the casting in System Verilog looks like it might help, but
that's not supported yet in many of the tools we use.

Ideas? Comments? Pointers?

Thanks!!

David
 
Sliced reference must be preceeded by an identifier in Verilog, hence
there's not much you can do about it if you use macros/defines. Unless
you assign the macros/defines to an intermediate identifier and then do
the slicing.

However, one possible solution I can think of is mask the
macros/defines to the sliced you want to achieve for example, if you
want to get the second hex, you could (((h0000F0 & ADDR) >> 16) ==
XXX[32:16]), this might work .....

Joe
LogicSim - Your Personal Verilog Simulator
http://www.logicsim.com

unfrostedpoptart wrote:
Hi all.

I'd like some help/opinions from the group. I've got a design that
uses parameters as constants for register/memory addresses, e.g.
parameter ADDR1 = 24'h10_0000;
parameter ADDR2 = 24'h10_0010;

Since these are used globally, in many synthesizable blocks and
testbench files, I'd rather use macros/`defines so that each module
doesn't have to include the parameter file inside the module. However,
I've got a catch: in many places I need to use a slice of the
constant, e.g.:

if (XXX[23:10] == ADDR1[23:10]) ....

and this won't work if I use a macro (e.g. `define ADDR1 24'h10_0000).
Some of the casting in System Verilog looks like it might help, but
that's not supported yet in many of the tools we use.

Ideas? Comments? Pointers?

Thanks!!

David
 
unfrostedpoptart wrote:
Hi all.

I'd like some help/opinions from the group. I've got a design that
uses parameters as constants for register/memory addresses, e.g.
parameter ADDR1 = 24'h10_0000;
parameter ADDR2 = 24'h10_0010;

Since these are used globally, in many synthesizable blocks and
testbench files, I'd rather use macros/`defines so that each module
doesn't have to include the parameter file inside the module. However,
I've got a catch: in many places I need to use a slice of the
constant, e.g.:

if (XXX[23:10] == ADDR1[23:10]) ....

and this won't work if I use a macro (e.g. `define ADDR1 24'h10_0000).
Some of the casting in System Verilog looks like it might help, but
that's not supported yet in many of the tools we use.

Ideas? Comments? Pointers?
....

One option is to use a module as a name space to keep these design wide
constants.

module Consts;

parameter ADDR1 = ...;

endmodule

and references of the form Consts.ADDR1 are legal.

You should check if the elaborator in your synthesis sofware permits
this.
 
ramesh@tharas.com wrote:
unfrostedpoptart wrote:
Hi all.
I'd like some help/opinions from the group. I've got a design that
uses parameters as constants for register/memory addresses, e.g.
parameter ADDR1 = 24'h10_0000;
parameter ADDR2 = 24'h10_0010;

Since these are used globally, in many synthesizable blocks and
testbench files, I'd rather use macros/`defines so that each module
doesn't have to include the parameter file inside the module. However,
I've got a catch: in many places I need to use a slice of the
constant, e.g.:

if (XXX[23:10] == ADDR1[23:10]) ....

and this won't work if I use a macro (e.g. `define ADDR1 24'h10_0000).
Some of the casting in System Verilog looks like it might help, but
that's not supported yet in many of the tools we use.

Ideas? Comments? Pointers?
...

One option is to use a module as a name space to keep these design wide
constants.

module Consts;

parameter ADDR1 = ...;

endmodule

and references of the form Consts.ADDR1 are legal.

You should check if the elaborator in your synthesis sofware permits this.
Thanks Ramesh - I used to do stuff like this years ago, but didn't
think of it now. I'll have to try it with all of our tools to make
sure we can use this method.

Here's another idea I tried, using macros with functions to extract
slices:




// Use macros instead of parameters for global constants
`define mZERO 32'h0
`define mONE 32'h00000001
`define mTWO 32'h00000002
`define mTHREE 32'h00000003
`define mFOUR 32'h00000004

`define mADDR32BIT 32'h1234_5678


`timescale 1ns/10ps

module
test_lint (
input clk, reset,
output reg [15:0] reg_16bits
);

// Current style parameter constants
parameter ZERO = 128'h0;
parameter ONE = 32'h00000001;
parameter TWO = 32'h00000002;
parameter THREE = 32'h00000003;
parameter FOUR = 32'h00000004;

parameter ADDR32BIT = 32'h1234_5678;



function [15:0] bits15to0 (
input [31:0] din);
bits15to0 = din[15:0];
endfunction // reg

function [31:10] bits31to10 (
input [31:0] din);
bits31to10 = din[31:10];
endfunction // reg


always @ (posedge clk) begin
if (reset) begin
reg_16bits[15:0] <= bits15to0(`mZERO); // new way: match
end // if (reset)
else begin
// reg_16bits[15:0] <= ADDR32BIT; // lint error: lhs != rhs
// reg_16bits[15:0] <= `mADDR32BIT ; // lint error: lhs != rhs
// reg_16bits[15:0] <= ADDR32BIT[15:0]; // old way: match
reg_16bits[15:0] <= bits15to0(ADDR32BIT); // new way: match
end // else: !if(reset)
end // always @ (posedge clk)

endmodule // test_lint
 

Welcome to EDABoard.com

Sponsor

Back
Top