I designed an ALU that does 4 operation depends on the value of op-code, and i used generate for conditional calling of sub module that i have to according to the project specification.But how i change the value of the parameter to move from one operation to another??
Here the code:
module ALU (A4, B4,cin4);
input [7:0] A4, B4;
input cin4;
//input [1:0] opc;
wire [7:0]out4;
wire cout4;
parameter opc=0;
generate
case (opc)
0: alu_add u1(out4,cout4,A4,B4,cin4); //calling an alu_add module
1: alu_sub u2(out4,cout4,A4,B4,cin4);
2: alu_comp u3_1(B4,out4);
3: alu_xor u4 (A4,B4,out4);
endcase
endgenerate
Parameters are for constants, and therefore can not be changed during simulation. Parameters can be overridden during instantiation.
What concerns me though is the use of the term call in the question. Generates are used to generate hardware based upon constants, ie they do not dynamically create and destroy hardware.
u1 to u4 are instances, describing physical hardware, what you have written at the minute is a ALU which can only do one thing. The code is configurable and given the user a choice of 4 things but once instanced then it is fixed.
To make a generic Generic ALU with all four operations available operations you need to select the output from the required ALU ie:
module ALU (
input [7:0] A4,
input [7:0] B4,
input cin4,
input [1:0] opc;
);
wire [7:0]out4, out4_0, out4_1, out4_2, out4_3;
wire cout4 ,cout4_0, cout4_1;
alu_add u1(out4_0,cout4_0,A4,B4,cin4); //calling an alu_add module
alu_sub u2(out4_1,cout4_1,A4,B4,cin4);
alu_comp u3_1(B4,out4_2);
alu_xor u4 (A4,B4,out4_3);
always #* begin
case (opc)
0: out4 = out4_0;
1: out4 = out4_1;
2: out4 = out4_2;
3: out4 = out4_3;
endcase
case (opc)
0: cout4 = cout4_0;
1: cout4 = cout4_1;
default: cout4 = 'b0;
endcase
end
endmodule
You can override a parameter's value when you instantiate the module. For example:
ALU #(.opc(1)) i1 ();
ALU #(.opc(2)) i2 ();
Refer to IEEE Std 1800-2012, Section "23.10.2.2 Parameter value assignment by name".
Related
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;
I'm newbie in ASIC design. I have a design with for example two inputs a ,b. I'm using the following code for initialize these two signals. But the Design compiler generating a warning that the register "a" is a constant and will be removed. When I'm trying to do post-synthesis simulation these two signals are all 'z'. So how can I apply initial signal assignment to avoid such a problem?
always #(posedge(clk) or posedge (rst)) begin
if (rst) begin
a<=4d'5;
b <=4'd10;
end
end
While describing hardware system, you need to consider that input signals to your module comes from another module/system and their values are decided by that signals. Inputs to any module can only be wire type.
You can think of a module as a box that has inputs and outputs. The values of output signals are decided by input signal + logic inside the box. However, the module cannot decide what its inputs should be. It is only possible if there is feedback, and even in that case it would depend on other signals that are outside of the module's control.
As a result, output signals can be declared as output reg but the same is not true for inputs. However there is solution to your problem, I think what you want can be designed using the following method:
module your_module(
input clk,
input rst,
//other inputs and outputs that you might need
input [3:0] a,
input [3:0] b
);
//define registers
reg [3:0] a_register;
reg [3:0] b_register;
/*
These registers are defined to make it possible to
to give any value to that logics when posedge rst
is detected, otherwise you can use them as your
input logics
*/
//use initial block if you need
always#(posedge clk or posedge rst) begin
if(rst) begin
a_register <= 4'd5;
b_register <= 4'd10;
end
else
begin
a_register <= a;
b_register <= b;
// and use a_register and b_register as you want to use a and b
end
end
endmodule
I am interested to know what will these lines synthesize to? I am designing a direct mapped cache and using assign to separate my index, offset and tag bits. Will it synthesize to a demultiplexer? I did not mention the whole code since I just want to know how the assign statements will look after synthesis. In 8085 programming, I had read the term as 'address demultiplexing" so it was confusing.
module cache
( input bit clk,
input bit rst,
input logic [15:0] address,
input logic valid_in,
input logic compare,
input logic wr,
input logic enable,
input logic write_through,
output logic dirty,
output logic [4:0] tag_out,
output logic [15:0] data_out,
output logic valid_out,
output hit
);
logic [7:0] index;
logic [1:0] offset;
logic [4:0] tag_in;
assign offset = address[1:0];
assign index = address[9:2];
assign tag_in = address[15:10];
endmodule
The above code will just simply get synthesized as wire's, since there are only assignments.
I am not sure what de-multiplexing logic you are trying to create, but generally for a de-multiplexer you need to have a select signal based on which you decode which output should be enabled.
An example for a 1:2 de-multiplexer logic is given below
module demux_1_2(
input [3:0] Q,
input Sel,
output reg [3:0] D1,
output reg [3:0] D2
);
always#(*)
begin
if(~Sel) begin
D1 = Q;
D2 = 0;
end else begin
D1 = 0;
D2 = Q;
end
end
endmodule
Since there are no Boolean or arithmetic operators on the RHS of the assign, these statements just become conveniently named references for part selects of the address input. This is the same thing that happens when you instantiate a module and connect to its ports - signals can go through a name change. In fact, you could have you could have written your address input port declaration as
input .address({tag_in,index,offset}),
You still connect the address port when instantiating this module, but inside the module, it only has tag_in, index, and offset available to reference, not address.
SystemVerilog has the alias construct to make it more obvious that you are just creating a convenient names for a signal, instead of declaring another set of signals and using the assign statement.
alias offset = address[1:0];
alias index = address[9:2];
alias tag_in = address[15:10];
How do I convert a tristate bus to 2-state logic for synthesis?
I've made a little test
module test1( inout tristate, output flattened);
assign flattened = tristate ? 1 : 0;
endmodule
module test2( inout tristate, output reg flattened);
always #(tristate) begin
case(tristate)
0: flattened = 0;
default: flattened = 1;
endcase
end
endmodule
`timescale 1ns / 1ps
module test_tb;
reg tristateEnable;
reg tristateValue;
wire tristate = tristateEnable ? tristateValue : 1'bz;
wire flattened1, flattened2;
test1 uut1(tristate, flattened1);
test2 uut2(tristate, flattened2);
initial begin
tristateValue = 1'b0;
tristateEnable = 1;
#10 tristateValue = 1'b1;
#10 tristateEnable = 1'b0;
end
endmodule
Simulating it I got that module test1 sets flattened to X and module test2 sets it to 1, the latter is what I wanted, but I haven't synthesized it yet. Is there a better / standard way of doing this?
You've asked two questions: (1) what is the difference between the conditional operator and the case statement, and (2) how to handle tri-state values.
On the language question:
In short, Verilog has a 4-state data type, and the operators handle the 4 states differently.
The case statement does a "4-state test", otherwise known as "case equality". The case expression (tristate in your example) is compared against 0, 1, x, and z. When it is z, the default branch is taken, so flattened is 1, as you found.
The conditional ('ternary') operator also does a 4-state test, and finds tristate as z. It doesn't know what to do now, so it combines the two values you supplied (0 and 1) into a resulting x, which is what you see. Basically, it's trying to be smart. See table 5-21 in the 2005 LRM.
Note that the if statement does not do a 4-state test.
Tristates: you're confused because your control signal (tristate) goes to z; it's the data signal (flattened) that should go to z.
You don't 'flatten' tristates for synthesis; you normally model a pull-up or pull-down. This will be specific to your technology, but you may just need to instantiate a pullup or pulldown component. Your synthesiser may or may not do this automatically for you if you have code like
assign sig_o = (ena == 1'b1)? sig_i : 1'bz;
You need to read your synthesiser docs to be sure. Note that you should only ever use a conditional operator like this if ena is guaranteed to be 2-state (0/1).
I am trying to count the number of ones in a 4-bit binary number in Verilog, but my output is unexpected. I've tried several approaches; this is the one I think should work, but it doesn't.
module ones(one,in);
input [3:0]in;
output [1:0]one;
assign one = 2'b00;
assign one = one+in[3]+in[2]+in[1]+in[0] ;
endmodule
First, you can't assign the variable twice.
Second, your range is off, 2 bits can only go from 0 to 3. You need a 3 bit output to count up to 4.
This is more like what you need:
module ones(
output wire [2:0] one,
input wire [3:0] in
);
assign one = in[3]+in[2]+in[1]+in[0] ;
endmodule
$countones can be used for this purpose (refer to IEEE Std 1800-2012, 20.9 Bit vector system functions):
module tb;
reg [3:0] in;
wire [2:0] one = $countones(in);
initial begin
$monitor("in=%b one=%d", in, one);
#1 in = 4'b0000;
#1 in = 4'b0001;
#1 in = 4'b1101;
end
endmodule
Output:
in=xxxx one=0
in=0000 one=0
in=0001 one=1
in=1101 one=3