StefanSchippers / xschem

A schematic editor for VLSI/Asic/Analog custom designs, netlist backends for VHDL, Spice and Verilog. The tool is focused on hierarchy and parametric designs, to maximize circuit reuse.
Other
300 stars 22 forks source link

Small Verilog Netlisting Issue: paramater not included when using verilog_format #145

Closed kwmartin closed 7 months ago

kwmartin commented 8 months ago

Background: Using xschem with iverilog and gtkwave to do some system level verilog sims of things like quadrature ddfs's, digital delta-sigma blocks, resonator-based digital filters, etc. To make testbenchs of new blocks, I use Python string templates to fill in an xschem generated verilog netlist (based on yaml configuration files to define specifics of different test benches). The xschem verilog netlister over-all is working extremely well; really well done Stefan! Small Issue, when I use the verilog_format symbol parameter, the block parameter is not being filled in. My symbol globals are:

type=subcircuit
verilog_format="@symname #( @bits ) @name ( @pinlist , @VDD , @VSS );"
template="name=x1 nbits=8 VDD=VDD VSS=VSS"
generic_type="nbits=int VDD=string VSS=string"
verilog_sym_def="tcleval(`include \"[abs_sym_path cmplt.v]\")"
verilog_extra="VDD VSS"
verilog_netlist=true

resulting in the following testbench template:

// sch_path: /home/martin/.xschem/proj_lib//CMPL_TB.sch
`timescale 1ps / 1fs
${TB_HEADER}
module CMPL_TB
(

);
wire [11:0] OUT ;
reg VDD ;
reg VSS ;
reg INVRT ;
reg [11:0] IN ;

CMPL #(  )  CMPL0 (  IN[11:0]   ,  INVRT  ,  OUT[11:0]   , VDD , VSS );
${TB_BODY}

endmodule

// expanding   symbol:  sym/CMPL.sym # of pins=3
// sym_path: /home/martin/.xschem/dig_lib//sym/CMPL.sym
`include "/home/martin/IC_Design/Verilog/cmplt.v"

Note in the instantiation, no parameter is present. With exactly the same everything, except commenting out the verilog_format parameter, I get a correct netlist (with explicit node connections), and now the parameter is present. I can attach a zip of the other files if needed.


type=subcircuit
xxxverilog_format="@symname #( @bits ) @name ( @pinlist , @VDD , @VSS );"
template="name=x1 nbits=8 VDD=VDD VSS=VSS"
generic_type="nbits=int VDD=string VSS=string"
verilog_sym_def="tcleval(`include \"[abs_sym_path cmplt.v]\")"
verilog_extra="VDD VSS"
verilog_netlist=true

Resulting Netlist:

// sch_path: /home/martin/.xschem/proj_lib//CMPL_TB.sch
`timescale 1ps / 1fs
${TB_HEADER}
module CMPL_TB
(

);
wire [11:0] OUT ;
reg VDD ;
reg VSS ;
reg INVRT ;
reg [11:0] IN ;

CMPL
#(
.nbits ( 12 )
)
CMPL0 ( 
 .IN( IN[11:0] ),
 .INVRT( INVRT ),
 .OUT( OUT[11:0] ),
 .VDD( VDD ),
 .VSS( VSS )
);

${TB_BODY}

endmodule

// expanding   symbol:  sym/CMPL.sym # of pins=3
// sym_path: /home/martin/.xschem/dig_lib//sym/CMPL.sym
`include "/home/martin/IC_Design/Verilog/cmplt.v"
StefanSchippers commented 8 months ago

hi @kwmartin,

I have the following instance in a verilog design: 1 the ram symbol has the following attributes:

type=subcircuit
vhdl_stop=true
verilog_netlist=true
format="@name @pinlist @symname"
template="name=x1 dim=5 width=8 hex=0 datafile=ram.list modulename=ram"
generic_type="datafile=string modulename=string"

_The verilog_netlist attribute is not needed unless you are doing a mixed VHDL/Verilog design that requires split netlisting mode (one file per module) and you have a simulator (like commercial Cadence Ncsim or Mentor Modelsim, don't know if they still are named like this) that is able to elaborate and link mixed (VHDL/Verilog) designs. You can leave it there, it has no side effects._

No need to use verilog_format at all. This is used for primitive devices, so something that does not have an underlying definition (= type not set to subcircuit)

verilog_format defines the netlisting rule (what is to be generated in the netlist for the symbol instantiation) if the symbol type is anything different from subcircuit. if you set for the symbol: type=primitive and (I have tuned this on my example): verilog_format="@symname #( @dim ) @name ( @pinlist , @VCC , @VSS );"

the verilog_format is correctly used: ram #( 11 ) xcoderam ( LDMBUS[15:0] , LDMADD[10:0] , LDDATA[15:0] , LDWEN_RAM , LDOEN_RAM , LDCK , LDCEN_RAM , LDMASK[15:0] , VCC , VSS ); However in this case no module expansion occurs. Xschem will not descend into the symbol. You can use a `include directive to include the definition.

The template attribute defines the default instance name (x1) followed by module parameters (if any).

The generic_type just defines parameter types that require special grammar, like strings (they need "..."), for integer types you don't need to define anything.

format is used for spice netlists, so it has no role in Verilog netlists.

This is the produced netlist (regarding the ram instance and ram module):

...
...
ram
#(
.dim ( 11 ) ,
.width ( 16 ) ,
.hex ( 0 ) ,
.datafile ( "ram.list" )
)
xcoderam ( 
 .LDDOUT( LDMBUS ),
 .LDADD( LDMADD[10:0] ),
 .LDDIN( LDDATA ),
 .LDWEN( LDWEN_RAM ),
 .LDOEN( LDOEN_RAM ),
 .LDCK( LDCK ),
 .LDCEN( LDCEN_RAM ),
 .LDM( LDMASK )
);
...
...
// expanding   symbol:  benacus/ram.sym # of pins=8
// sym_path: /home/schippes/xschem/xschem_library/benacus/ram.sym
// sch_path: /home/schippes/xschem/xschem_library/benacus/ram.sch
`timescale 1ps/1ps
module ram
#(
  parameter dim = 5,
  parameter width = 8,
  parameter hex = 0,
  parameter datafile = "ram.list",
  parameter modulename = "ram"
)
(
  output wire [width-1:0] LDDOUT,
  input wire [dim-1:0] LDADD,
  input wire [width-1:0] LDDIN,
  input wire LDWEN,
  input wire LDOEN,
  input wire LDCK,
  input wire LDCEN,
  input wire [width-1:0] LDM
);
...
...
// ram behavioral code follows...
..

You can add additional implicit (usually power) pins by using as you did verilog_extra="...." and adding the default assignment for these implicit (set by attributes) port connections.

kwmartin commented 7 months ago

Thank you Stephan, as allways, you are being exceedingly helpful. The type=primitive was something I missed. It turns out, I had a problem with the line:

verilog_format="@symname #( @bits ) @name ( @pinlist , @VDD , @VSS );"

The "#( @bits )" should have been "#( @nbits )". Once I corrected this, (and changed to type=primitive), I now am getting the parameter in the instantiation:

CMPL #( 12 )  CMPL0 (  IN[11:0]   ,  INVRT  ,  OUT[11:0]   , VDD , VSS );

Thank you. As an aside, is there a parameter that can choose explicit instatiation be used with verilog_format? I don't need this, but am just curious. As a somewhat related issue: I have noticed that when a "text" widget is added to a symbol close to the pin, and that when the text widget is added, this automatically updates the pin label parameter. I didn't see this in the documentation; I think it's very nice, and wonder how difficult it was to do.

kwmartin commented 7 months ago

Should have read "when the text widget is edited"

StefanSchippers commented 7 months ago

A text object being edited will update also the name=... attribute of the nearby pin. As a suggestion when editing such text objects always verify if the nearby pin is updated accordingly. The pin update is done if text and pin name=... have identical content and are "sufficiently" close (the exact limit distance is set by heuristic and common sense, so it is not perfect for all cases). If the text is CLK and the nearby pin has name=CLK, changing the text to CLK1 will also change the pin name to name=CLK1. If the text is CLK and pin has name=CLK2, changing text to CLK1 will not update the pin.

StefanSchippers commented 7 months ago

As an aside, is there a parameter that can choose explicit instatiation be used with verilog_format? I don't need this, but am just curious.

you may have a verilog_format attribute in the symbol, like: verilog_format="@symname #( @dim , @width , @hex ) @name ( @pinlist );" this format will be used if present. If you change this to: xverilog_format="@symname #( @dim , @width , @hex ) @name ( @pinlist );" the leading 'x' character will change the attribute to something xschem does not know about, so it will not be used. you can enable it any time by removing the x character.