why output of a module can't reach from outside module - verilog

I write two module by Verilog.
first module is 4 bit counter:
module ASYNCHRONOUS_COUNTER( clk, res, out);
input clk;
input res;
output[3:0] out;
reg[3:0] out;
wire clk;
wire res;
initial
out = 4'b0;
always #(negedge clk or posedge res)
if(res) begin
out[0] <= 1'b0;
end else begin
out[0] <= ~out[0];
end
always #(negedge out[0] or posedge res)
if(res) begin
out[1] <= 1'b0;
end else begin
out[1] <= ~out[1];
end
always #(negedge out[1] or posedge res)
if(res) begin
out[2] <= 1'b0;
end else begin
out[2] <= ~out[2];
end
always #(negedge out[2] or posedge res)
if(res) begin
out[3] <= 1'b0;
end else begin
out[3] <= ~out[3];
end
endmodule
second module use first module :
module tripleInputClk(clk,tripledClk);
input clk;
wire clk;
output tripledClk;
wire tripledClk;
wire res;
wire[3:0] out;
reg temp;
initial
temp <= 1'b0;
//assign out = 3'b0;
assign res = ~out[3] & ~out[2] & out[1] & out[0];
ASYNCHRONOUS_COUNTER myCounter(
.clk(clk),
.res(res),
.out(out)
);
always #(posedge res)
begin
temp <= ~temp;
end
assign tripledClk = temp;
endmodule
first module works correctly, but when I compiled it and made it's wave form ,I understood that outputs of first module doesn't pass correctly and value of 'res' always equal '0'.

Here, res is declared as wire in your tripleInputClk module.
I simulated your code and observed that the signal tripledClk goes HIGH after three clock pulses. Thereby, suspecting that a posedge of res signal must occur. But, res is in continuous assignment statement. As soon as res becomes HIGH, the reg out changes (#(posedge res)) and again makes res LOW; all this in a single time stamp. So you are not able to view transition of res signal.
Also, after that, the tripledClk signal does not toggle as expected, I guess.
One way out is to declare res as reg in tripleInputClk module and remove it from continuous assignment. Instead, make it work on the edge of clock signal only.
This is because, reg is used to store values. Here, there is a circular dependency of res on out and vice-versa (i.e. out is also dependent on res). Henceforth, it creates some sort of confusing conditions(I would not term it as a race around condition exactly).
When you'll proceed to synthesis (even though initial block is not synthesizable here..!), the tool may issue this circular dependency warning. And, proper hardware may not be formed.
I've modified your code and provided a testbench to it. The only change is the one that I described here, i.e. res signal. Kindly go through the link below. The tripledClk is now also working fine as (3*frequency_of_clk).
Link to EDAPlayground.

Related

How to create positive edge detector behavioural code?

I'm currently trying to code a positive edge detector that changes its output every time a positive edge is detected. I succeeded in building one with gate-level modelling, but now I need to build it using behavioral modelling. I tried building it using this foundation:
module pos_edge_det ( input sig,
input clk,
output pe);
reg sig_dly;
always # (posedge clk) begin
sig_dly <= sig;
end
assign pe = sig & ~sig_dly;
endmodule
I tried making code where in every positive edge it detects on the input, the output will always invert:
module posedgedet(in, out, clk, res);
input wire in,clk,res;
output wire out;
always # (posedge in, posedge clk)
begin
out <= ~out;
end
endmodule
When compiling, it returned this following error
Error: C:/Modeltech_pe_edu_10.4a/examples/pos edge detect.v(8): (vlog-2110) Illegal reference to net "out".
What does this error mean, and how do you properly use the always code to detect a positive edge on both input and clock pulse?
The error means that you can not declare out as a wire when you assign to it inside an always block. You need to declare out as a reg. I posted your module on edaplayground and compiled it on several simulators, one of which produced this slightly more specific error message:
out is declared here as wire.
At least that gives you a hint that there is something wrong with using wire.
There is also a problem with this line:
always # (posedge in, posedge clk)
That will not be synthesized into a flip-flop.
I think you are looking for a module which will detect a posedge on sig and generate an output pe which will be a single-clock wide pulse and also generate an output out which will toggle every time a posedge on sig is seen. I'm assuming your res signal is a reset. I also included a simple testbench.
module pos_edge_det (
input sig,
input clk,
input res,
output pe,
output reg out
);
reg sig_dly;
always # (posedge clk or posedge res) begin
if (res) begin
sig_dly <= 0;
end else begin
sig_dly <= sig;
end
end
assign pe = sig & ~sig_dly;
always # (posedge clk or posedge res) begin
if (res) begin
out <= 0;
end else if (pe) begin
out <= ~out;
end
end
endmodule
module tb;
reg clk, res, sig;
wire pe, out;
initial begin
clk = 0;
forever #5 clk =~clk;
end
pos_edge_det dut (
// Inputs:
.clk (clk),
.res (res),
.sig (sig),
// Outputs:
.out (out),
.pe (pe)
);
initial begin
sig = 0;
res = 1;
#20 res = 0;
repeat (10) #30 sig = ~sig;
#5 $finish;
end
endmodule

I2S Transmitter Verilog Implementation not working

I am trying to implement the I2S Transmitter in verilog. The datasheet for it is at: https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf
I wrote the code, but my SD line is delayed 1 clock cycle when i test it.
Can someone check my implementation?
module Transmiter(
input signed [23:0] DLeft, input signed [23:0] DRight, input WS, input CLK,
output reg SD
);
wire PL;
reg Q1,Q2;
reg [23:0] shift_reg;
reg [23:0] Tdata;
assign PL = Q1^Q2;
always #(posedge CLK)
begin
Q1 <= WS;
Q2 <= Q1;
end
always #( Q1) begin
if (Q1)
begin
Tdata <= DRight;
end
else
begin
Tdata <= DLeft;
end
end
always #(negedge CLK)
begin
if(PL)
begin
shift_reg <= Tdata;
end
else begin
SD <= shift_reg[23];
shift_reg <= {shift_reg[22:0],1'b0};
end
end
endmodule
EDIT: here is a image of waveform image
TEST BENCH CODE:
module Transmitter_tb(
);
reg CLK, WS;
reg [23:0] dataL;
reg [23:0] dataR;
wire SDout;
Transmiter UT(dataL, dataR, WS, CLK, SDout);
initial begin
dataL = 24'hF0F0FF; #2;
dataR = 24'h0000F0; #2;
end
always begin
CLK=0; #20;
CLK=1; #20;
end;
always begin
WS=0; #1000;
WS=1; #1000;
end;
endmodule
Your negedge block contains an if-else construct and will only ever compute one or the other on a single clock edge. SD will therefore not change value when PL is high.
Furthermore you are using non-blocking assignments(<=) in your code. This roughly means that changes won't be evaluated until the end of the always block. So even if SD <= shift_reg[23] after shift_reg <= Tdata it will not take on the new value in shift_reg[23] but use the previous value. If you want SD to change immediately when shift_reg[23] changes you need to do this combinatorically.
This should work:
always #(negedge CLK)
begin
if(PL)
begin
shift_reg <= Tdata;
end
else
shift_reg <= {shift_reg[22:0],1'b0};
end
assign SD = shift_reg[23];
Working example: https://www.edaplayground.com/x/4bPv
On a side note I am still not convinced that DRight and DLeft are in fact constants, I can see that they are in your TB but it doesn't make sense that the data for your I2S is constant. Your current construct will probably generate a latch(instead of a MUX), and we generally don't want those in our design.
You should clean up your use of blocking versus non-blocking statements:
Always use non-blocking assigments, meaning "<=", in clocked statements.
Always use blocking assigments, meaning "=", in combinational (non-clocked) statements.
This is a industry-wide recommendation, not a personal opinion. You can find this recommendation many places, see for instance:
http://web.mit.edu/6.111/www/f2007/handouts/L06.pdf
The sensitivtity list being incomplete (as pointed out by #Hida) may also cause issues.
Try to correct these two things, and see if it starts working more as expected.
Also note that you are using Q1 (among other signals) to generate your PL signal. If the WS input is not synchronous to your local clock (as I assume it is not), you need to put one more flop (i.e. two in series) before starting to use the output, to avoid metastability-issues. But you won't see this in an RTL simulation.

4 bit countetr using verilog not incrementing

Sir,
I have done a 4 bit up counter using verilog. but it was not incrementing during simulation. A frequency divider circuit is used to provide necessory clock to the counter.please help me to solve this. The code is given below
module my_upcount(
input clk,
input clr,
output [3:0] y
);
reg [26:0] temp1;
wire clk_1;
always #(posedge clk or posedge clr)
begin
temp1 <= ( (clr) ? 4'b0 : temp1 + 1'b1 );
end
assign clk_1 = temp1[26];
reg [3:0] temp;
always #(posedge clk_1 or posedge clr)
begin
temp <= ( (clr) ? 4'b0 : temp + 1'b1 );
end
assign y = temp;
endmodule
Did you run your simulation for at least (2^27) / 2 + 1 iterations? If not then your clk_1 signal will never rise to 1, and your counter will never increment. Try using 4 bits for the divisor counter so you won't have to run the simulation for so long. Also, the clk_1 signal should activate when divisor counter reaches its max value, not when the MSB bit is one.
Apart from that, there are couple of other issues with your code:
Drive all registers with a single clock - Using different clocks within a single hardware module is a very bad idea as it violates the principles of synchronous design. All registers should be driven by the same clock signal otherwise you're looking for trouble.
Separate current and next register value - It is a good practice to separate current register value from the next register value. The next register value will then be assigned in a combinational portion of the circuit (not driven by the clock) and stored in the register on the beginning of the next clock cycle (check code below for example). This makes the code much more clear and understandable and minimises the probability of race conditions and unwanted inferred memory.
Define all signals at the beginning of the module - All signals should be defined at the beginning of the module. This helps to keep the module logic as clean as possible.
Here's you example rewritten according to my suggestions:
module my_counter
(
input wire clk, clr,
output [3:0] y
);
reg [3:0] dvsr_reg, counter_reg;
wire [3:0] dvsr_next, counter_next;
wire dvsr_tick;
always #(posedge clk, posedge clr)
if (clr)
begin
counter_reg <= 4'b0000;
dvsr_reg <= 4'b0000;
end
else
begin
counter_reg <= counter_next;
dvsr_reg <= dvsr_next;
end
/// Combinational next-state logic
assign dvsr_next = dvsr_reg + 4'b0001;
assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg;
/// Set the output signals
assign y = counter_reg;
endmodule
And here's the simple testbench to verify its operation:
module my_counter_tb;
localparam
T = 20;
reg clk, clr;
wire [3:0] y;
my_counter uut(.clk(clk), .clr(clr), .y(y));
always
begin
clk = 1'b1;
#(T/2);
clk = 1'b0;
#(T/2);
end
initial
begin
clr = 1'b1;
#(negedge clk);
clr = 1'b0;
repeat(50) #(negedge clk);
$stop;
end
endmodule

D-flip flop with 2 reset: synthesis error

I'm doing a synthesis of a digital block and I need a D-Flip-Flop with 2 asynchronous resets.
(The reason is that I will drive one reset with an available clock, and I will use the second one to reset all the registers of my digital block)
I prepared the following code:
module dff_2rst(q,qn,clk,d, rst,clear);
input clk,d, rst, clear ;
output q,qn;
reg q,qn;
always #(posedge clk or posedge rst or posedge clear) //asynchronous reset
begin
(* full_case, parallel_case *)
case({rst, clear})
2'b00: begin
q <= d;
qn<=~d;
end
default: begin
q <= 1'b0;
qn <=1'b1;
end
endcase
end
endmodule
But I get the following error:
The statements in this 'always' block are outside the scope of the synthesis policy. Only an 'if' statement is allowed at the top level in this always block. (ELAB-302)
*** Presto compilation terminated with 1 errors. ***
I also tried with
if(~rst & ~clear)
but I have errors too.
Do you have an idea to correct my code? Thanks a lot!
The standard way to write a async reset, set (clear) flip-flop in Verilog RTL is:
always #(posedge clk or posedge rst or posedge clear) begin
if (rst) begin
// Aysnc Reset
q <= 'b0 ;
end
else if (clear) begin
// Async Clear
q <= 'b0 ;
end
else begin
// Sync logic here
q <= d;
end
end
assign qn = ~n;
The little trick for qn requires it qn be a wire, currently defined as a reg. reg q,qn; should just be reg q;
Also for cleaner code a new header type is cleaner and avoids repetition:
module dff_2rst(
input clk,
input d,
input rst,
input clear,
output reg q,
output qn );
Thank you Morgan. Your code was inspiring to me. I couldn't use
assign qn=~q;
Because I got the error:
qn is not a valid left-hand side of a continuous assignment.
But I modified your code in the following manner and it works:
module dff_2rst(q,qn,clk,d, rst,clear);
input clk,d, rst, clear ;
output q,qn;
reg q,qn;
always #(posedge clk or posedge rst or posedge clear) //asynchronous reset
//
begin
if (rst) begin
// Aysnc Reset
q <= 'b0 ;
qn<= 'b1 ;
end
else if (clear) begin
// Async Clear
q <= 'b0 ;
qn<= 'b1 ;
end
else begin
// Sync logic here
q <= d;
qn<= ~d;
end
end
endmodule

Does not work as before Verilog initial construction in ModelSim Altera Edition 10.4

Since version 10.4, start problem with initial block. Like this:
reg [31:0] init_ram[15:0];
initial begin
init_ram[0] = 32'h1234_5678;
init_ram[1] = 32'h8765_4321;
...
end
always_ff #(posedge clk)
init_ram[addr] <= data;
Or
module test(
input clk,
...
output reg a
);
initial a = 1'b1;
always #(posedge clk)
a <= ...;
ModelSim 10.4 error:
Error (suppressible): (vlog-7061) {path} Variable 'init_ram' driven in
an always_ff block, may not be driven by any other process
In older versions all works well.
You don't know which ModelSim parameter should I change to fix it?
One of the problems with the always_ff and always_comb constructs is that they are supposed to check the synthesizability during simulation, except that there is no standard for what is synthesizable. If the intent is that the initial blocks are just for simulation, then you will need to change the always_ff to always or change the initial block to use force/release instead.
One idea for a work around to your problem is to add a reset
signal and use it to initialize the value of a register.
Well, probably this
would be a good way to give an initial value to your flip-flops.
This should be something like:
reg [31:0] init_ram[15:0];
input reset;
always_ff #(posedge clk) begin
if (reset) begin
init_ram[0] <= 32'h1234_5678;
init_ram[1] <= 32'h8765_4321;
end
else begin
init_ram[addr] <= data;
Or this:
module test(
input clk,
input reset,
...
output reg a
);
always #(posedge clk) begin
if (reset) begin
a <= 1'b1;
end
else begin
a <= ...;

Resources