Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 module gray_counter( input clk, input reset, input dir, output [2:0] out ); wire [2:0] stato_attuale; reg [2:0] eccitazione; always @(posedge clk) begin if (dir == 0) begin eccitazione[0] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0])); eccitazione[1] <= ((~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & stato_attuale[0])); eccitazione[2] <= ((~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0])); end else if (dir == 1) begin eccitazione[0] <= ((stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0])); eccitazione[1] <= ((stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & stato_attuale[0])); eccitazione[2] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0])); end end FF ff0 (.X(eccitazione[0]), .C(eccitazione[0]), .R(reset), .Z(stato_attuale[0])); FF ff1 (.X(eccitazione[1]), .C(eccitazione[1]), .R(reset), .Z(stato_attuale[1])); FF ff2 (.X(eccitazione[2]), .C(eccitazione[2]), .R(reset), .Z(stato_attuale[2])); assign out[0] = stato_attuale[0]; assign out[1] = stato_attuale[1]; assign out[2] = stato_attuale[2]; endmodule module FF( input X, C, R, output Z ); reg y1, y2; always @(posedge C or posedge R) begin if (R) begin y1 <= 1'b0; y2 <= 1'b0; end else begin y1 <= (~y2 & C & X) | (y1 & (~C | ~y2)); y2 <= y1 ^ C; end end assign Z = y1; endmodule
module gray_counter(
input clk,
input reset,
input dir,
output [2:0] out
);
reg [2:0] stato_attuale;
reg [2:0] eccitazione;
always @(posedge clk or posedge reset) begin
if (reset) begin
stato_attuale <= 3'b000;
end else begin
stato_attuale <= eccitazione;
end
end
always @(*) begin
if (dir == 0) begin
eccitazione[0] = ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) |
(~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]));
eccitazione[1] = ((~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & stato_attuale[0]));
eccitazione[2] = ((~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]));
end else if (dir == 1) begin
eccitazione[0] = ((stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) |
(~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) |
(~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]));
eccitazione[1] = ((stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) |
(~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]));
eccitazione[2] = ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]));
end
end
assign out = stato_attuale;
endmodule
Thanks for the idea, but I wanted to keep the flip-flops, as it was an exercise to create a counter using the given flip-flop as the memory cell. The logic is correct, it's just a problem of Verilog syntax. The counter simply stops working when the dir signal changes and I need help fixing it.You can modify your code like this:
Code:module gray_counter( input clk, input reset, input dir, output [2:0] out ); reg [2:0] stato_attuale; reg [2:0] eccitazione; always @(posedge clk or posedge reset) begin if (reset) begin stato_attuale <= 3'b000; end else begin stato_attuale <= eccitazione; end end always @(*) begin if (dir == 0) begin eccitazione[0] = ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0])); eccitazione[1] = ((~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & stato_attuale[0])); eccitazione[2] = ((~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0])); end else if (dir == 1) begin eccitazione[0] = ((stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0])); eccitazione[1] = ((stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & stato_attuale[0])); eccitazione[2] = ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0])); end end assign out = stato_attuale; endmodule
Here
The eccitazione register is computed combinationally based on the current state stato_attuale and the dir signal.
The stato_attuale register is updated on each clock cycle if reset is not active.
The reset signal ensures that the counter starts from a known state (0 in this case).
The logic is correct...
.The counter simply stops working.
What do you mean?I've seen counting go downward when taking output from Q pin of D flip-flops. To count upward I find I must take output from bar-Q pins.
I'm assuming my logic is correct, I think this is just a verilog syntax problem.
Well, then, I guess you've just invented Schroedinger's logic, it works and doesn't work at the same time!
What does this mean? You expect a Verilog compiler bug?I'm assuming my logic is correct, I think this is just a verilog syntax problem
Then I guess my logic is wrong... but I don't know where. My counter stops when dir changes value and I don't know whyWhat does this mean? You expect a Verilog compiler
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 always @(posedge C or posedge R) begin if (R) begin y1 <= 1'b0; y2 <= 1'b0; end else begin y1 <= (~y2 & C & X) | (y1 & (~C | ~y2)); y2 <= y1 ^ C; end end
Code Verilog - [expand] 1 2 3 4 5 6 always @(posedge C or posedge R) begin if (R) Z <= 1'b0; else Z <= X; end
Thank you man, I wanted to remain the closest possible to this flipflop (it was an exercise):Your so-called "flip-flop" code is garbage. It neither models an edge triggered nor level triggered flip-flop correctly.
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 always @(posedge C or posedge R) begin if (R) begin y1 <= 1'b0; y2 <= 1'b0; end else begin y1 <= (~y2 & C & X) | (y1 & (~C | ~y2)); y2 <= y1 ^ C; end end
The @(posedge C) construct is right for edge triggered logic. But then C must not appear in the edge sensitive logic expression.
Simpled edge triggered FF
Code Verilog - [expand] 1 2 3 4 5 6 always @(posedge C or posedge R) begin if (R) Z <= 1'b0; else Z <= X; end
I think I've found the error, basically the counter should change value everytime the clk change, but I have posedge C and non posedge clk. The time that at least one of the input of ff does not change from 0 to 1 the counter stops, as there is not a posedge C that rule the flipflop.I need help to create a 3-bit Gray code counter that can count both forwards and backwards. Using flip-flops as memory, I was able to create a counter but only in one direction. The dir signal, despite changing, cannot reverse the counting direction. The flip-flop needs to have the same value as input to change the exit. I noticed that the counter counts only in the direction it is in at the time of the reset. When dir = 0 it should count from 0 to 7 and when dir = 1 from 7 to 0. I do not waant to change the flipflop.
This is the simulation:
This is the verilog code:
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 module gray_counter( input clk, input reset, input dir, output [2:0] out ); wire [2:0] stato_attuale; reg [2:0] eccitazione; always @(posedge clk) begin if (dir == 0) begin eccitazione[0] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0])); eccitazione[1] <= ((~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & stato_attuale[0])); eccitazione[2] <= ((~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0])); end else if (dir == 1) begin eccitazione[0] <= ((stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) | (~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0])); eccitazione[1] <= ((stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) | (~stato_attuale[2] & stato_attuale[1] & stato_attuale[0])); eccitazione[2] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) | (stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0])); end end FF ff0 (.X(eccitazione[0]), .C(eccitazione[0]), .R(reset), .Z(stato_attuale[0])); FF ff1 (.X(eccitazione[1]), .C(eccitazione[1]), .R(reset), .Z(stato_attuale[1])); FF ff2 (.X(eccitazione[2]), .C(eccitazione[2]), .R(reset), .Z(stato_attuale[2])); assign out[0] = stato_attuale[0]; assign out[1] = stato_attuale[1]; assign out[2] = stato_attuale[2]; endmodule module FF( input X, C, R, output Z ); reg y1, y2; always @(posedge C or posedge R) begin if (R) begin y1 <= 1'b0; y2 <= 1'b0; end else begin y1 <= (~y2 & C & X) | (y1 & (~C | ~y2)); y2 <= y1 ^ C; end end assign Z = y1; endmodule
Usually (binary) counters change state on one clock edge only. Not on both edges.basically the counter should change value everytime the clk change, but I have posedge C and non posedge clk.
Posedge triggered versus negedge triggered is what I was getting at. By experimenting with my simulations of counters, the scope traces indicate that changes of state depend on whether polarities are one way or the opposite way. In other words, whether positive edge triggered or negative edge triggered. It has to do with Q versus not-Q outputs.What do you mean?
My flipflop exit are stato_attuale[], and my inputs for the flipflops based on the output are eccitazione[]
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?