I have this 4 bit ring counter that I'm trying to make, and I feel like I'm so close, but I can't figure out how to make one input depend on the previous state's output. Here's what I have:
`default_nettype none
// Empty top module
module top (
// I/O ports
input logic hz100, reset,
input logic [20:0] pb,
output logic [7:0] left, right
);
// Your code goes here...
q[3:0];
assign q[3:0] = right[3:0];
hc74_set setFF(.c(pb[0]), .d(pb[1]), .q(right[0]), .sn(pb[16]));
hc74_reset resetFF1(.c(pb[0]), .d(pb[1]), .q0(right[1]), .rn(pb[16]));
hc74_reset resetFF2(.c(pb[0]), .d(pb[1]), .q1(right[2]), .rn(pb[16]));
hc74_reset resetFF3(.c(pb[0]), .d(pb[1]), .q2(right[3]), .rn(pb[16]));
endmodule
// Add more modules down here...
// This is a single D flip-flop with an active-low asynchronous set (preset).
// It has no asynchronous reset because the simulator does not allow it.
// Other than the lack of a reset, it is half of a 74HC74 chip.
module hc74_set(input logic d, c, sn,
output logic q, qn);
assign qn = ~q;
always_ff #(posedge c, negedge sn)
if (sn == 1'b0)
q <= 1'b1;
else
q <= d;
endmodule
// This is a single D flip-flop with an active-low asynchronous reset (clear).
// It has no asynchronous set because the simulator does not allow it.
// Other than the lack of a set, it is half of a 74HC74 chip.
module hc74_reset(input logic d, c, rn,
output logic q, qn);
assign qn = ~q;
always_ff #(posedge c, negedge rn)
if (rn == 1'b0)
q <= 1'b0;
else
q <= d;
endmodule
This is on an FPGA simulator, which is why there are a few things like pb (these are push buttons) and left, right outputs which are sets of 8 LEDs each.
Let's first make sure we are on the same page
Based on wikipedia description of a ring counter
This could be implemented as follows:
module top (
// I/O ports
input logic reset_n,
input logic clk,
output logic [3:0] ring
);
// Your code goes here...
always #(posedge clk or negedge reset_n) begin
if(~reset_n) begin
ring = 4'b0001;
end
else begin
ring[0] <= ring[3];
ring[1] <= ring[0];
ring[2] <= ring[1];
ring[3] <= ring[2];
end
end
endmodule
The output ring is a 4-bit one hot vector, reset_n = 0 makes ring = 0001 every clock with reset_n = 1 rolls the ring to the right, [0001, 0010, 0100, 1000, 0001, ...].
But you want to use instances of the flops you defined. Notice that in an assignment a <= b, a is the output of the flop (q port), and b is the input of the flop (d port).
module top (
// I/O ports
input logic reset_n,
input logic clk,
output logic [3:0] ring
);
// Your code goes here...
hc74_set setFF(.c(clk), .d(ring[3]), .q(ring[0]), .sn(reset_n));
hc74_reset resetFF1(.c(clk), .d(ring[0]), .q0(ring[1]), .rn(reset_n));
hc74_reset resetFF2(.c(clk), .d(ring[1]), .q1(ring[2]), .rn(reset_n));
hc74_reset resetFF3(.c(clk), .d(ring[2]), .q2(ring[3]), .rn(reset_n));
endmodule
You have to connect the ports accordingly, I just used clk for the clock and reset_n for the negated reset signal.
I am looking to design a serial to parallel converter in Verilog which converts a fast clock serial input to a slower clock parallel input. I tried the following code which works in RTL but does not verify on Cadence Conformal. nclk is 16 times faster than clk. The serial data comes in at nclk and the parallel data is intended to come out at clk rate.
sEEG - Serial Input
eegOut - Parallel output
I can only have clk and nclk as my operation references due to tape-out bond pad limitations.
Following is the code that I have come up with which works well in functional simulation but Formal Verification fails.
module deserializer(sEEG, nclk, clk, eegOut);
input sEEG;
input nclk,clk;
reg [15:0] temp;
output reg [15:0] eegOut;
reg [4:0] i;
always #(negedge nclk) begin
temp[i] = sEEG;
i = i + 1;
end
always#(posedge clk) begin
i<=0;
eegOut <= temp;
end
endmodule
I feel you should use four bits in order to index 16 elements. If you parameterize the module, this could be done with:
# (parameter WIDTH = 16)
then later use it as:
localparam BIT_SEL = $clog2(WIDTH); //..this should give you "4" if WIDTH = 16
reg [BIT_SEL-1:0] i;
Also, you might want to include a clock synchronizer, you don't want metastability problems, an easy way to do this is to include "double-triggers", practically is to buffer the data and replicate it to the next slow clock cycle (adds 1 slow clock cycle latency). So, maybe this works:
module deserializer
# (parameter WIDTH = 16)
(sEEG, nclk, clk, eegOut);
input sEEG;
input nclk,clk;
reg [WIDTH-1:0] temp;
reg [WIDTH-1:0] temp_reg; //..synchronizer
output reg [WIDTH-1:0] eegOut;
always #(negedge nclk) begin
temp[WIDTH-2:0] <= temp[WIDTH-1:1];
temp[WIDTH-1] <= sEEG;
end
always#(posedge clk) begin
temp_reg <= temp;
eegOut <= temp_reg;
end
endmodule
The code is written in 1999 and controls a CNC machine. If the code snippet is not adequate to determine the language i can upload the entire file. This is the code segment:
BEGIN CONDITION +S_P0_PRES AND +N_P0__PNLTST ON EXCEPTION BEGIN
SET N_P0_STB OFF
SET N_P0_KEY(*) TO BITS(0)
SET N_P0_LTS(*) TO BITS(0)
SET ..KEY_PLS(*) TO BITS(0)
SET S_P0_KEY_PLS(*) TO BITS(0)
SET S_NCX0_FLEDS(*) TO BITS(0)
IF
:-S_P0_PRES: BEGIN
SET N_P0_ACT OFF
RETURN
END
END IF
WAIT +N_P0__PNLTST OR -S_P0_PRES
END
IF
:+N_P0_STB: BEGIN
LET ..KEY_INX = 0
REPEAT WHILE [INT(..KEY_PLS(*)) <> 0]
IF
:+..KEY_PLS(..KEY_INX): BEGIN
IF
:[..KEY_NUM(..KEY_INX) < 128]: BEGIN
IF
:-..KEY_ISF(..KEY_INX): SET N_P0_KEY(..KEY_NUM(..KEY_INX)) OFF
:+..KEY_ISF(..KEY_INX): SET .P0_NCX_FUN(..KEY_NUM(..KEY_INX)) OFF
END IF
START N_P0__NCXKEY
END
:[..KEY_NUM(..KEY_INX) < LAST(N_P0_KEY(*)) + 1]: BEGIN
SET N_P0_KEY(..KEY_NUM(..KEY_INX)) OFF
START N_P0__MAIKEY
END
:[..KEY_NUM(..KEY_INX) < LAST(.P0_NCX_FUN(*)) + 1]: BEGIN
SET .P0_NCX_FUN(..KEY_NUM(..KEY_INX) - (LAST(N_P0_KEY(*)) - 127)) OFF
START N_P0__FKEY
END
END IF
I think you're looking at APT.
My partial program is as followed, it's a FSM to handle the traffic light,and the register "times" (from 4 to 1) is to compute the time that the traffic light should brighten, But whenever "times" counts to "1", the time of "times=1" is longer than other "times" about one clock.
For example:when times = 4~2,every clock will count ,but when times=1,it will take two clocks
to become times=4.
Could anybody tell me how this problem happened?
always#(posedge clk or negedge rst )
if(!rst)
begin
s1<=state1;
A<=3'b0;
B<=3'b0;
count1<=3'd4;
count2<=3'd2;
count3<=3'd3;
count4<=3'd2;
temp<=1'b1;
end
else
begin
if(temp==1)
begin
temp<=1'b0;
case(s1)
state1:
begin
times<=count1;
A<=3'b001;
B<=3'b100;
s1<=state2;
end
state2:
begin
times<=count2;
A<=3'b010;
B<=3'b100;
s1<=state3;
end
state3:
begin
times<=count3;
A<=3'b100;
B<=3'b001;
s1<=state4;
end
state4:
begin
times<=count4;
A<=3'b100;
B<=3'b010;
s1<=state1;
end
default:
begin
A[0]<=3'b000;
B[0]<=3'b000;
end
endcase
end
else
begin
if(times>1)
times<=times-1;
else if(times==1)
begin
temp<=1'b1;//can't count averagely
end
end
end
I am making a parallel to serial converter using ring counter in verilog. The ring counter is working fine but the Parallel to serial converter is not working properly and I am getting x undefined result. I am providing the code kindly help me finding the problem.
TOP
module PtoSTOP;
reg clk,rst;
wire [3:0] myout;
wire out;
Ring a(clk,rst,myout);
parToser x(myout,clk,rst,out);
initial begin
clk=1;
rst=1;
#1 rst=0;
end
always
#2 clk=~clk;
endmodule
Parallel TO Serial Converter
module parToser(myout,clk,rst,out);
input clk,rst;
input [3:0] myout;
output reg out;
reg [2:0]i;
always #(posedge clk or posedge rst) begin
if(rst) begin
out <= 0;
i <= 0;
end
else begin
out <= myout[i];
i <= i+1;
end
end
endmodule
RingCounter
module Ring(clk,rst,myout);
input clk,rst;
output reg [3:0]myout;
always #(posedge clk or posedge rst) begin
if(rst)
myout<=1;
else
myout<=myout<<1;
end
endmodule
I think the main issue you are seeing is part of parToser.
You have reg [2:0]i; which you increment and use to address input [3:0] myout; but i can hold values 0 to 7, half of which is outside the address range of [3:0] myout. You should be seeing a simulation error about out of range addressing.
Also you have included a few flip-flops with a reset condition but not added the reset to the sensitivity list in 'parToser' & 'Ring':
always #(posedge clk)
Should be:
always #(posedge clk or posedge rst)
With out this trigger your out, i and myout variables will be x, as they have not been set to a known condition.
NB: parToser i = i+1; should be i <= i+1;