Modeling skewed delay for combinational logic - system-verilog

I need help to model a block with different delays for various input-output paths?
input A;
input [3:0] B, C;
output [3:0] Y;
Y = B xor C if A = 1 else Y = 0
with A->Y delay of 10us when posedge A (rise delay) and 5us when negedge A(fall delay)
and B,C - > Y delay is 1us (applicable only if A = 1)
For my case, I might need to use procedural way and assign statements might not suit.

Here is something that worked best for me.
`timescale 1us/1ns
module xor_w_enabled(input A, input B, input C, output Y);
wire A_delayed;
wire B_xor_C_delayed;
assign #1 B_xor_C_delayed = B^C;
assign #(10,5) A_delayed = A;
assign Y = (A_delayed == 1) ? B_xor_C_delayed : 0;
endmodule
Please let me know if I'm missing anything.

For non-synthesizable models you can use #delay constructs combined with `timescale to model delays. something like the following code
`timescale 1us/1us
module delayModule(A,B,C,Y);
input A;
input [3:0] B, C; // this should probably be output
output [3:0] Y;
reg [3:0] tmpb, tmpy;
always #(posedge A)
#10us tmpb <= 1;
always #(negedge A)
#5us tmpb <= 0;
always #* begin
if (A == 1)
#1us tmpy =(B^C);
end
assign B = tmpb;
assign Y = tmpy;
endmodule // delayModule

Related

Continuous variable used in clocked when clause is automatically discretized

model test
import Modelica.Constants.pi;
Real f;
discrete Real g;
Clock clk=Clock(0.1);
equation
f = sin(pi*time);
when Clock(0.1) then
if f >= 0 then
g = (sin(pi*time)) - 0.1;
else
g = (sin(pi*time)) + 0.1;
end if;
end when;
end test;
f is assigned as a continuous function. I want to sample the value of g depended on f, but f also be changed to a discrete value. Is there anything wrong ?
The clock partitioning sees f as being used directly inside the when Clock and thus f is also seen as a clocked variable.
Use sample(f) if that is not desired:
model test
import Modelica.Constants.pi;
Real f;
discrete Real g;
Clock clk=Clock(0.1);
equation
f = sin(pi*time);
when Clock(0.1) then
if sample(f) >= 0 then
g = (sin(pi*time)) - 0.1;
else
g = (sin(pi*time)) + 0.1;
end if;
end when;
end test;
See also: Failure to handle clock inference in Dymola

Can't output results of calculations

I'm trying to output the result of some multiplications and adders. As far as I can tell I've coded everything correctly (system compiles, seems consistent with examples I've seen) but it doesn't output the values of any assigned/calculated variables. Clearly there is something wrong or missing.
I've pasted my code below:
module multiplier_4x4(
logic [1:0] a,b,
output logic [3:0] c,
logic [3:0] p,
input logic cin = 0,
output logic cout = 0
);
assign a = 2'b11;
assign b = 2'b11;
assign c[0] = a[0] & b[0];
fulladder FA1(a[1]&b[0], a[0]&b[1], 1'b0, c[1], p[0]);
fulladder FA2(b[1]&a[1], 1'b0, cin, c[2], p[1]);
assign c[3] = p[1];
initial begin
$display("Output %d", c[1]);
$display("Output %d", c);
$display("Output %d", a);
$display("Output %d", a[0]);
$display("Output %d", 1'b1);
end
endmodule
module fulladder(input logic a, b, cin,
output logic s, cout);
wire p, g;
assign p = a ^ b;
assign g = a & b;
assign s = p ^ cin;
assign cout = g | (p & cin);
endmodule
The display lines output the following (in order of appearance):
x
x
x
x
1
I would have expected the x values to represent actual numbers/variables. Where did I go wrong?
The simulation in the post does nothing because it was running for 0 time.
Make this change so that it runs for at least a single time step before displaying the results:
initial begin
#1;
$display("Output %d", c[1]);
$display("Output %d", c);
$display("Output %d", a);
$display("Output %d", a[0]);
$display("Output %d", 1'b1);
end
Produces:
# Output 0
# Output 5
# Output 3
# Output 1
# Output 1

How to cope with the error of the following piece of system verilog code?

schematic
I would like to write system verilog code to implement this schematic (using 3 2:4 decoder and 64 3-input and gate to achieve a 6:64 decoder), and the following is my piece of code:
module Ex4( input logic [5:0] D,
output logic [63:0] y
);
genvar i;
genvar j;
genvar k;
integer n = 0;
logic [3:0] y1, y2, y3;
dec2 d1(D[1:0], y1);
dec2 d2(D[3:2], y2);
dec2 d3(D[5:4], y3);
generate
begin
for(i = 0; i < 3; i = i + 1) begin:flp1
for (j = 0; j < 3; j = j + 1) begin:flp2
for(k = 0; k < 3; k = k + 1) begin:flp3
and3_new a_n(y1[i], y2[j], y3[k], y[n]);
n=n+1; // error message comes from this line
end
end
end
end
endgenerate
endmodule
Note: "dec2" and "and3_new" are two modules written in advance with no problems
However, I got the following error during compilation, can anybody give me some hint? Thank you.
Error (10170): Verilog HDL syntax error at Ex4.sv(22) near text: "=";
expecting ".", or "(". Check for and fix any syntax errors that appear
immediately before or at the specified keyword. The Intel FPGA
Knowledge Database contains many articles with specific details on
how to resolve this error. Visit the Knowledge Database at
https://www.altera.com/support/support-resources/knowledge-
base/search.html and search for this specific error message number.
You can't put a procedural assignment statement in that position. Instead of [n], use [i*16+j*4+k]. You can also do
module Ex4( input logic [5:0] D,
output logic [63:0] y
);
logic [3:0] y1, y2, y3;
dec2 d1(D[1:0], y1);
dec2 d2(D[3:2], y2);
dec2 d3(D[5:4], y3);
for(genvar i = 0; i < 4; i++) begin:flp1
for (genvar j = 0; j < 4; j++) begin:flp2
for(genvar k = 0; k < 4; k = k + 1) begin:flp3
parameter n = i*16+j*4+k;
and3_new a_n(y1[i], y2[j], y3[k], y[n]);
end :flp3
end : flp2
end : flp1
endmodule

Modelica: Mixing connectors and direct inputs

The following Modelica package - while neither being particularly useful nor interesting - does not yield any warnings.
package P
connector C
Real c;
end C;
model A
input C x;
output Real y;
equation
y = x.c;
end A;
model B
input C inp;
output C out;
A a;
equation
a.x = inp;
out.c = a.y;
end B;
end P;
However, when A does not use connectors as in the following case, there is a warning: The following input lacks a binding equation: a.x. Clearly, there is a binding equation for a.x. Why is there such a warning?
package P
connector C
Real c;
end C;
model A
input Real x;
output Real y;
equation
y = x;
end A;
model B
input C inp;
output C out;
A a;
equation
a.x = inp.c;
out.c = a.y;
end B;
end P;
The issue here is that there is not a binding equation. There is only an ordinary equation. A binding equation is one that is applied as a modification to the element, e.g.
model B
input C inp;
output C out;
A a(x=inp.c) "Binding equation";
equation
out.c = a.y;
end B;
Note that in general, if two things are connectors, they should not be equated, they should be connected. That will help you avoid this issue. So in your first version of B:
model B
input C inp;
output C out;
A a;
equation
connect(a.x, inp);
out.c = a.y;
end B;
The reason for the binding equation restriction has to do with making sure components are balanced. You can read more about that in the specification or in Modelica by Example. By using it as a binding equation, it makes it clear that this equation can be used to solve for this variable (i.e., the term in the equation containing that variable won't vanish or be ill-conditioned).

2 Bit Counter using JK Flip Flop in Verilog

I'm writing verilog code of 2 Bit Counter using JK Flip Flop that counts 0-3 and back to 0. I'm using Xilinx EDA. However I'm keep getting one error and I don't know what it means? The line numbers doesn't show up here, but error is located at "always #(posedge clk)".
ERROR:HDLCompiler:1401 - "C:\Users\Eduardo\Documents\SFSU\Fall 2014\Engr 378\Lab 3\TwoBitCounter\twobitcounter.v" Line 30: Signal q in unit jkff is connected to following multiple drivers:
`timescale 1ns / 1ps
module twobitcounter( q_out, qbar_out, j,k, clk, reset);
input [1:0] j; input [1:0] k; input clk; input reset;
output [1:0] q_out;
output [1:0] qbar_out;
wire [1:0] q_out;
wire [1:0] qbar_out;
wire clk;
assign qbar_out[0] = ~q_out[0];
assign j[0] = 1;
assign k[0] = 1;
assign j[1] = q_out[0];
assign k[1] = q_out[0];
jkff M1(q_out[0], qbar_out[0], j[0], k[0], clk, reset);
jkff M2(q_out[1], qbar_out[1], j[1], k[1], qbar_out[0]);
endmodule
module jkff(output q_out, output qbar_out,
input j, input k, input clk, input reset);
reg q;
assign q_out = q;
assign qbar_out = ~q;
initial begin
q = 1'b0;
end
always #(posedge clk)
begin
case({j,k})
{1'b0, 1'b0}: begin
q = q;
end
{1'b0, 1'b1}: begin
q = 1'b0;
end
{1'b1, 1'b0}: begin
q = 1'b1;
end
{1'b1, 1'b1}: begin
q = ~q;
end
endcase
end
always #(posedge reset)
begin
q = 1'b0;
end
endmodule
The issue is q is being set in two always blocks, which is not allowed in synthesis. Merge the two always blocks. Also, q is a flop, so it should be assigned using non-blocking assignment (<=), not blocking assignment (=).
always #(posedge clk or posedge reset)
begin
if (reset == 1'b1) begin
q <= 1'b0;
end
else begin
case({j,k})
{1'b0, 1'b0}: begin
q <= q;
end
{1'b0, 1'b1}: begin
q <= 1'b0;
end
{1'b1, 1'b0}: begin
q <= 1'b1;
end
{1'b1, 1'b1}: begin
q <= ~q;
end
endcase
end
end
You should almost never use initial blocks in synthesizable code. Most FPGAs allow it for initialization. ASICs designs however do not support it. For both cases, if there is an asynchronous reset/set then it initial block shouldn't be used.
The error is telling you that you are assigning q in different blocks. This creates an error. You are assigning q in both your initial block and your always block.
You should never use initial blocks in synthesizable code.