I'm trying to learn my way through this issue as well. I'm trying to look at examples from FPGA Prototyping by Verilog Examples Spartan 3 Edition as well as what google gives me. The examples seem a bit limited compared to what I'd like to do, showing only one parameter instead of many, showing one width parameter when I want many different width definitions for different register types, (i2c data vs dadr, shift register vs bit counter) and I'd like to include a file there to share some of these parameters with various modules defined in different files (an i2c communicator module, a testbench module, and a register file module each in their own files all `including the i2c_params.v file)
Some of what I have done may be causing verilog 95 and verilog 2001 conflicts, I don't know enough yet to tell what is a problem or how to fix t well.
I do NOT want to use instantiation-overriding of any parameters at this point, I just want a single place to define these things and leave the values as they are defined. I've been strongly discouraged from using `defines or that's how I'd have done all this from the beginning.
Lets try to make up some examples rather than copy my work files:
file i2c_params.v
- Code: Select all
parameter I2C_DATA_BITS = 8; //I2C data is sent one byte at a time with ack in between bytes
parameter I2C_DATA_MSB = I2C_DATA_BITS - 1;
parameter I2C_SHIFT_REG_BITS = I2C_DATA_BITS; //shift register is same size as i2c data
parameter I2C_SHIFT_REG_MSB = I2C_SHIFT_REG_BITS - 1;
parameter I2C_DADR_BITS = 7,
I2C_DADR_MSB = I2C_DADR_BITS - 1;
//currently have an 8-bit data size, with ack bit gives 9 transfer bits
// which fits in 4-bit counter
parameter SDA_COUNTER_BITS = 4,
SDA_COUNTER_MSB = SDA_COUNTER_BITS - 1;
file i2c.v
- Code: Select all
module i2c
//parameters
#(
`include "i2c_params.v"
)
//I/O port declarations
(
input wire clock,
input wire reset,
input wire sdain,
input wire sclin,
input wire [I2C_DATA_MSB:0] read_data, //data to be read from config registers -
// always current value of selected register
// regardless of read/write operation
input wire [I2C_DADR_MSB:0] id_config, //inputs to set i2c slave address
output wire sdaout, //to sda pad (open-collector pullup on board)
output reg [I2C_DATA_MSB:0] write_data, //data to be written to config registers
...
)
... rtl implementation code
endmodule
file testbench.v
- Code: Select all
`timescale 1 ns / 1 ps
`include "i2c.v"
`include "tb_regfile.v"
module testbench;
// no I/O ports for testbench
//include verilog tasks from other files
`include "i2c_params.v"
//should these be localparams instead? I wrote a lot of this before learning about 2001's new parameter/localparam styling
//temporarily use faster timing for simulation run time reduction
// parameter sys_clk_period = 31; //32MHz is 31.25ns period, round to 31
parameter sys_clk_period = 8; //32MHz is 31.25ns period, round to 31
// parameter scl_period = 2500; //i2c 400KHz clock is 2500ns period
parameter scl_period = 400; //i2c 400KHz clock is 2500ns period
reg tb_sys_clk; //system clock
reg tb_sys_reset; //active-high reset
reg [I2C_SHIFT_REG_MSB:0] tb_sda_shiftreg;
reg [SDA_COUNTER_MSB:0] tb_sda_bit_counter;
//registers the testbench will control as if it was i2c master
reg tb_scl;
reg tb_scl_prev;
wire tb_scl_posedge;
wire tb_scl_negedge;
reg [I2C_DADR_MSB:0] tb_id_config; //selected base address for i2c slave
wire tb_sda_to_DUT;
reg tb_sda_data_to_DUT;
reg tb_sda_ack_to_DUT;
reg tb_sda_to_DUT_prev;
wire tb_sda_to_DUT_posedge;
wire tb_sda_to_DUT_negedge;
wire tb_sda_from_DUT; //sda output from the i2c DUT
reg tb_ack_from_DUT;
wire [I2C_DATA_MSB:0] tb_read_data;
wire [I2C_DATA_MSB:0] tb_write_data;
wire tb_read_reg;
wire tb_write_reg;
reg tb_i2c_busy;
reg tb_i2c_start_cond;
reg tb_i2c_stop_cond;
reg [I2C_DADR_MSB:0] test_dadr; //a different parameter name than most places
reg test_read_writen;
reg [I2C_DATA_MSB:0] test_iadr;
reg [I2C_DATA_MSB:0] tb_byte_expected;
reg tb_ack_expected;
integer tb_error_count;
wire [I2C_DATA_MSB:0] test_dadr_w; //combined dadr and read_write bits
reg [I2C_DATA_MSB:0] tb_byte_from_DUT;
reg [I2C_DATA_MSB:0] tb_byte_to_transmit;
...
//various other regs/wires and testbench code
...
i2c DUT_i2c (port connections); //no instantiation parameter overrides here
test_regfile i2c_regfile(port connections); //no instantiation parameter overrides here
initial
begin
... //simulation commands to communicate with the DUT_i2c
end
endmodule
I'm trying to compile/simulate using Cadence irun from our ius-5.6SR1 toolset and am getting this error:
- Code: Select all
parameter I2C_DATA_BITS = 8; //I2C data is sent one byte at a time with ack in between bytes
|
ncvlog: *E,EXPRPA (i2c_params.v,4|27): expecting a right parenthesis (')') [12.1(IEEE-2001)].
For the i2c.v file, I am using the I/O port declaration style of input reg [I2C_DADR_MSB:0] i2c_dadr rather than simply list port names there and do input/output and reg/wire sections later on. The portlist was given to me in this format, and my attempts to split it into the separate portname, input/output and reg/wire groups just led to a lot of errors which I didn't understand so I left it this way. Examples seem to do parameter group, then I/O portnames, then the input/output and reg/wire groups for the ports, OR do I/O portnames, then parameters, then input/output and reg/wire groups for the ports. I've nto found anything anywhere that does an include, so I'm wondering if it's legal for what I want to do, and I do not know another way to accomplish my goal.
That's a missing close paren on line 4 of the i2c_params.v include file, previous lines are all comment or whitespace.
Do I need to adjust my style here from a 95 way of doing things in the i2c_params.v file? Is this include parameters style simply not allowed?
Do I need to change it to a chain of parameters separated by commas rather than redoing the parameter keyword in different groups of parameter names?
Are there any more advanced examples of parameter usage out there more like what I'm trying to do?