Now I'm trying to understand some verilog code as the below,
dataproc #(10) proc01
(
.dout (dout01[9:0]),
.clk (clkin01),
.rst_n (rst_in01_n),
.din (dout[9:0])
);
actually I didn't get the purpose of this
#(10)
what is this? and what is the purpose in the verilog?
I'm usually using as the below way
dataproc u_dataproc
(
...
...
)
But I never been seen the before
#(10)
update
I've update the module.
module dataproc
#(parameter w = 1)
(
input clk,
input rst_n,
input [w-1:0] din,
output wire [w-1:0] dout
);
reg [w-1:0] NP_dout;
assign dout = NP_dout;
endmodule
It's a parameter, which you are overriding while making the instance of the module.
Suppose you have a module like below.
module temp();
parameter a = 2;
bit [a-1:0] b1;
endmodule
Now if you take instance of the above module and want to change the default parameter value (which in turn change the underlying hardware of that module), then you can do something like follow.
module abc();
temp t1();
temp #(4) t2(); // Changes the default parameter value
initial
begin
$display("Size of t1.b1 - %0d", $size(t1.b1));
$display("Size of t2.b1 - %0d", $size(t2.b1));
end
endmodule
// Output
Size of t1.b1 - 2
Size of t2.b1 - 4
Please note that parameters must be having a value before runtime or
in elaboration time. So you can't change parameters during simulation
run.
Related
I want to "mask" an input unpacked array given a specific signal. If that signal is 1, I want the input to be all zeroes instead of the given array.
module thing (
input clk,
input rst,
input packedBits[`PB_SIZE]
);
// ...
endmodule
module top (
input clk,
input rst
);
logic packedBits[`PB_SIZE];
mod_i thing (
.clk(clk),
.rst(rst),
// I can manually put `PB_SIZE zeroes, but I want the compiler to do it for me
.packedBits(rst ? {0,...,0} : packedBits)
)
endmodule
Putting just {0,0,0,0} when `PB_SIZE is 4 works, but how could I do it in a more generic way?
You can use the replication operator:
.packedBits(rst ? '{`PB_SIZE{0}} : packedBits)
Refer to IEEE Std 1800-2017, section 5.11 Array literals.
Here is a complete example on EDA playground. It runs on Cadence and Synopsys, but there are errors on Mentor. It seems Mentor does not support this syntax yet.
Simulators sometimes struggle with complex expressions connected to module ports. It is usually a good idea to simplify the connection using a separate signal.
`define PB_SIZE 5
module thing (input packedBits [`PB_SIZE]);
initial #1 $display("%m %p", packedBits);
endmodule
module tb;
bit rst = 1;
logic packedBits [`PB_SIZE];
logic packedBitsGated [`PB_SIZE] = rst ? '{`PB_SIZE{0}} : packedBits;
thing mod_i (.packedBits(packedBitsGated));
initial begin
packedBits = '{`PB_SIZE{1}};
#1 $display("%m %p", packedBits);
end
endmodule
This works on all 3 simulators on EDA playground.
You can use a default in an assignment patterns. Then there is no need to know its size.
.packedBits(rst ? '{default:0} : packedBits)
I am trying to wire a Verilog Structural description of an Edge-triggered T flip-flop with an synchronous reset (R). Here is the circuit for this element:
Now assume that I have already written the behavioral description for each block in this schematic , so here is my structural description for this circuit by instantiation of each of this blocks in the circuit:
module edge_trig_flipflop_structure (
input x,y,clk,
output q,
wire a,b,c,d
);
inv u1(c,q);
mux_2x1 u2 (q,c,x,a);
inv u3(d,y);
and_2_1 u4(b,a,d);
d_flipflop u5(b,clk,q);
endmodule
Is this a good efficient code for this circuit? In other words, do I really need the two extra wires used for the inverters which are the wires c and d Or, is there another efficient way to write this code?
Edit : Here is the code for each component to know the order of ports in the declaration of each component
module mux_2x1 (
input a,
input b,
input sel,
output reg c
);
always # (*) begin
case ( sel)
1'b0: c=a;
1'b1: c=b;
default : $dispaly ("error");
endcase
end
endmodule
module d_flipflop ( input d,clk , output reg q);
always # (posedge clk ) begin
q=d;
end
endmodule
module inv(output reg b, input a);
always # (a) begin
b=~a;
end
endmodule
module and_2_1 ( output reg c,input a,b);
always #(a or b) begin
if (a==1'b1 & b==1'b1)
c= 1'b1;
else
c=1'b0;
end
endmodule
By default, Verilog does not require you to declare all signals. If signals appear in port connections, they will implicitly be 1-bit wire types.
However, it is good practice to declare all signals explicitly with wire, as you have done.
You could also change the default behavior and require explicitly declared signals using this compiler directive:
`default_nettype none
Since you are also concerned about connections, it is a good practice to make connections by name instead of connections by position. It is more verbose, but it will help avoid simple connection errors. For example:
inv u1 (.b(c), .a(q));
I got compile errors on your module header. You probably meant to code it this way:
module edge_trig_flipflop_structure (
input x,y,clk,
output q
);
wire a,b,c,d;
When declaring a module in Verilog (2001?), is it possible to tell that some ports are vectors without indicating their size? The goal here is to handle vector ports of any size, without having to specify the sizes through parameters.
I know I can write something like what follows in Verilog, but I'd like to know if there's a way to get rid of the extra WIDTH_DATA parameter:
module my_module
#(
parameter WIDTH_DATA = 48
)
(
input Clk, En,
input [WIDTH_DATA-1:0] Data_in,
output Ready,
output reg [WIDTH_DATA-1:0] Data_out
);
This is possible in VHDL, using a declaration like that:
entity my_module is
port (
Clk : in std_ulogic;
En : in std_ulogic;
Data_in : in std_ulogic_vector;
Ready : out std_ulogic;
Data_out : out std_ulogic_vector
);
end entity;
The module implementation can then know the size of Data_in at compile time using Data_in'length (same for Data_out).
This is not possible in Verilog.
You can do something close to what you want in SystemVerilog using the interface construct. You can parameterize an interface, and connect that interface (or set of interfaces) to my_module.
interface my_intf #(int WIDTH);
logic [WIDTH-1:0] data;
endinterface
module my_module(input clk, en,
my_intf in, out,
output ready);
// $bits(in.data) - gives you the WIDTH
// typedef type(out.data) out_type // local typedef
endmodule
module top;
my_intf #(8) I1;
my_intf #(16) I2;
bit clk, en, ready;
my_module M1 (.clk,.en, .in(I1), .out(I2), .ready);
endmodule
I designed a RAM module, and I need multiple instances of this module each with a different memory initialization file.
The Quartus manual says that Quartus supports the $readmemh() function to initialize RAM. So I added two parameters to this module and pass different parameters to each instance, in order to specify which files each instance will read.
My code below works in Modelsim, but when fails when synthesizing. Quartus crashes, and after I remove it, Quartus synthesizes successfully.
module cell_module
#(
parameter X_ID = "1",
parameter Y_ID = "1",
parameter DIR_ID = {X_ID, "_", Y_ID}
)
...
reg [15:0] Mem_1 [0:31];
reg [15:0] Mem_2 [0:31];
`ifdef SIM_MEM_INIT
initial begin
$readmemh ({"../data", DIR_ID, "/file1.txt"},Mem_1);
$readmemh ({"../data", DIR_ID, "/file2.txt"},Mem_2);
end
`endif
The above module is instantiated in the top level like this:
cell_module #(.X_ID("1"), .Y_ID("1")) cell_module1 (...)
cell_module #(.X_ID("1"), .Y_ID("2")) cell_module2 (...)
cell_module #(.X_ID("2"), .Y_ID("1")) cell_module3 (...)
cell_module #(.X_ID("2"), .Y_ID("2")) cell_module4 (...)
The parameters specify which folder contains the initial memory for that cell.
This code works in Modelsim, and Quartus analysis and elaborate successfully completes.
But it causes quartus_map to crash when synthesizing. I can't find any information about this error message.
If this isn't possible, are there any good methods to initialize multiple instance's RAM with different contents?
Thanks
EDIT:
I built a small Quartus project to test whether this could be done. I followed the Quartus manual and wrote a standard RAM module with two extra parameters to define the folder of the initialization memory file.
This is code of ram,
module mem_init
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=6, parameter X_ID = "1", Y_ID = "1", DIR_ID = {X_ID,"_", Y_ID})
(input [(DATA_WIDTH-1):0] data,
input [(ADDR_WIDTH-1):0] addr,
input we, clk,
output [(DATA_WIDTH-1):0] q);
reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_reg;
initial
begin : INIT
$readmemh ("../data", DIR_ID, "/file.txt", ram);
end
always # (posedge clk)
begin
if (we)
ram[addr] <= data;
addr_reg <= addr;
end
assign q = ram[addr_reg];
endmodule
And its initialization:
mem_init #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(ADDR_WIDTH), .X_ID("1"), .Y_ID("1"))
mem1 (.data(data1), .addr(add1), .we(we), .clk(clk), .q(q1));
mem_init #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(ADDR_WIDTH), .X_ID("1"), .Y_ID("2"))
mem2 ( .data(data2),.addr(add2),.we(we), .clk(clk), .q(q2));
This works in simulation and Quartus successfully synthesizes this design.
"initial block" is not supported by the IEEE-1800 standard for synthesis.
If Altera/Intel lets you get away with that, then there is this issue, in terms of hierarchical references, that may help you too:
https://github.com/YosysHQ/yosys/issues/344
you can implement a reset signal.
always (posedge clock or posedge reset)
begin
if(reset==0)
begin
$readmemh ("../data", DIR_ID, "/file.txt", ram);
end
end
it will help you; I think.
once again check what will be synthesizable in Verilog.
I would like to write a module with a variable number of inputs, i.e. depending on some parameter, the result would be:
module my_module #(LENGTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data_1
);
//...
endmodule
or
module my_module #(LENGTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data_1,
input [LENGTH-1:0] data_2,
input [LENGTH-1:0] data_3
);
//...
endmodule
Would it be possible to do this in Verilog or Systemverilog or would I have to write a script, let's say in Python, in order to generate the code for a specific module with fixed number of inputs? (it might be more than 1000 inputs)
There are no variable number of ports in SystemVerilog, but you could use a port that is a parameterized array.
module my_module #(int LENGTH, DEPTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data[DEPTH]
);
//...
endmodule
Otherwise, you would need to use a script to generate the code.
Use a two dimensional input with a parameterized size. Added a generate for loop that can be used to set signals individually. Although many operations can be done with smart array operations.
module my_module #(SIZE, LENGTH)(
input clk,
input rst_n,
input [SIZE-1:0][LENGTH-1:0] data_in_array,
output [SIZE-1:0][LENGTH-1:0] data_out_array
);
genvar N;
generate for (N=0; N<SIZE; N++) begin :la_coolOps
//Do cool operations here. For example instantiate a module for every data_in
end
//...
endmodule
Edit:
As Mehran Torki points out: The syntax above will work for SystemVerilog only. Verilog does not allow for multiple packed arrays. Use input [LENGTH*SIZE-1:0] data_in_array.
I would add to these other answers that ports are just groupings of wires. While having 3, 1-bit wires named a, b, and c might be easier to read and understand, there is no physical/logical difference between a single, 3-bit wire abc, where abc[0] corresponds to a, abc[1] corresponds to b, and abc[2] corresponds to c.
So, you can always just expand or shrink a single (or multiple) signal(s) to get however many bits you need. It may not be as neat, but it will work. In the receiving module, you can then part-select the bus in whatever manner you like. So, you could have one really long wire the shrinks or expands (wire [(SOME_PARAM*8)-1:0] my_input_wire), or with SystemVerilog an array (wire [7:0] my_input_wire[0:SOME_PARAM-1])
If this is just testbench/verification code, the other thing you could do in SystemVerilog is use a dynamic array
As others said, there is no direct way to do this, but another workaround is to use SystemVerilog interfaces, where you define all the inputs that you want in the interface definition and inside the module only use the ones that correspond to the parameter. Below is a sample:
module my_module #(LENGTH)(
input clk;
input rst_n;
output o;
interface i_data;
);
logic outValue;
generate
case (LENGTH) //Based on the value of LENGTH, use corresponding data
1: outValue = i_data.data_1;
2: outValue = i_data.data_1 + i_data.data_2;
3: outValue = i_data.data_1 + i_data.data_2 + i_data.data_3;
endcase
endgenerate
always #(posedge clk) begin
if (~rst_n)
o <= '0;
else
begin
o <= outValue;
end
endmodule
You can still use a parameterized array for data and a for-generate loop if your outputs are similar.
With System verilog we can import a package instead of having parameterization and define types in the package to be used in the portlist.
module mymodule
import mymodule_pkg::*;
(
input portlist_t portlist
);
endmodule
And define multiple copies of the package with different variants of the port list and compile whichever version is required. eg
package mymodule_pkg;
localparam LENGTH=5;
typedef struct packed {
logic [LENGTH-1:0] data_1,
logic [LENGTH-1:0] data_2,
logic [LENGTH-1:0] data_3
} portlist_t;
endpackage
As with the interface solution there will be situations where you run into issues, like having different iterations of the module instantiated together.