module seg_controller(
clk,
reset,
sel,
seg,);
input clk;
input reset;
output wire [5:0] sel;
output wire [7:0] seg;
wire [9:0] count;
wire [3:0] d_in;
counter use_counter(clk, reset, count);
FSM(count, reset, sel, d_in);
dec_7seg(d_in,seg);
endmodule
At this part, I don't know how to connect modules each others.
Each modules have many variables, but except input clk, reset how should i use variables in count, d_in.
just use wire?
module counter
(clk,
reset,
count);
input clk;
input reset;
output reg [9:0] count;
always # (posedge clk)
begin
if(reset) count <= 0;
else count <= count + 1;
end
endmodule
module FSM (
count,
reset,
sel,
d_in);
input [9:0]count;
input reset;
output reg [5:0] sel;
output reg [3:0] d_in;
reg [5:0] state, nextstate;
parameter S0 = 6'b100_000;
parameter S1 = 6'b010_000;
parameter S2 = 6'b001_000;
parameter S3 = 6'b000_100;
parameter S4 = 6'b000_010;
parameter S5 = 6'b000_001;
always # (*)
begin
if(reset) sel = 6'b100_000;
else if(count == 10'b11_1111_1111)
state = nextstate;
d_in = d_in + 1;
end
always # (*)
case(state)
S0: nextstate = S1;
S1: nextstate = S2;
S2: nextstate = S3;
S3: nextstate = S4;
S4: nextstate = S5;
S5: nextstate = S0;
default: nextstate = S0;
endcase
always # (*)
if(state == S0) begin
sel = S0; end
else if(state == S1) begin
sel = S1; end
else if(state == S2) begin
sel = S2; end
else if(state == S3) begin
sel = S3; end
else if(state == S4) begin
sel = S4; end
else begin
sel = S5; end
endmodule
At this part
if(state == S0) begin
sel = S0; end
Error (10028): Can't resolve multiple constant drivers for net "sel[4]" at FSM.v(44)
I don't know why this massage come out.
module dec_7seg(
d_in,
seg
);
input [3:0]d_in;
output [7:0]seg;
wire [3:0]d;
assign d[3] = ~ d_in[3];
assign d[2] = ~ d_in[2];
assign d[1] = ~ d_in[1];
assign d[0] = ~ d_in[0];
assign seg[0] = ~(d[3] & d[2] | d[3] & d[1]);
assign seg[1] = ~(~d[2] & d[1] | d[2] & ~d[1] | d[3] & d[0] | d[1] & ~d[0]);
assign seg[2] = ~(d[3] & ~d[2] | d[3] & d[1] | ~d[3] & d[2] & ~d[1] | d[2] &
d[1] & ~d[0] | ~d[2] & ~d[1] & ~d[0]);
assign seg[3] = ~(d[3] & d[2] | d[3] & d[1] | ~d[2] & ~d[0] | d[1] & ~d[0]);
assign seg[4] = ~(d[2] & ~d[1] & d[0] | d[3] & ~d[1] | ~d[2] & d[1] & d[0] |
~d[3] & ~d[2] & ~d[0] | d[2] & d[1] & ~d[0]);
assign seg[5] = ~(~d[3] & d[2] | d[3] & ~d[2] | ~d[1] & d[0] | ~d[2] & ~d[1]
| ~d[2] & d[0]);
assign seg[6] = ~(~d[3] & d[1] & d[0] | d[3] & ~d[1] & d[0] | d[3] & d[1] &
~d[0] | ~d[3] & ~d[1]& ~d[0] | ~d[2] & ~d[1] | ~d[2] & ~d[0]);
assign seg[7] = ~(~d[3] & d[1] | d[2] & d[1] | ~d[2] & ~d[0] | d[3] & ~d[2]
& ~d[1] | ~d[3] & d[2] & d[0]);
endmodule
I want to make it work. But i'm a beginner at verilog.
There are too many problem what i don't know why.
So I want to know the direction to solve that terrible codes...
Your problem is that you are assigned sel here
always # (*)
begin
if(reset) sel = 6'b100_000; // <-- You should assign
// state and d_in here only
else if(count == 10'b11_1111_1111)
state = nextstate;
d_in = d_in + 1;
end
And then assigning sel in another process
always # (*)
if(state == S0) begin
sel = S0; end
else if(state == S1) begin
sel = S1; end
else if(state == S2) begin
sel = S2; end
else if(state == S3) begin
sel = S3; end
else if(state == S4) begin
sel = S4; end
else begin
sel = S5; end
endmodule
I think you want it come up in S0 on reset, so you might try this
always # (*)
if(state == S0 || reset) begin // Now you reset sel and assign in
sel = S0; end // the same process
else if(state == S1) begin
sel = S1; end
else if(state == S2) begin
sel = S2; end
else if(state == S3) begin
sel = S3; end
else if(state == S4) begin
sel = S4; end
else begin
sel = S5; end
Related
For a lab I must create the logic to use on a Digilent PMOD ALS. In the lab requirenment I cannot use the sclk signal on the sensitivity list and therefore use a state machine to create the 2.5 MHz clk signal to send to the PMOD ALS. See the code below:
module sens_interface(
input clk, //clk 10Mhz
input reset_n,
input [15:0] delay,
input datain,
output reg sclk,
output reg cs_n,
output reg [3:0] Cout,
output reg [3:0] Dout,
output reg [5:0] cnt
);
//params
//state machine 1
parameter SA0 = 3'b000;
parameter SA1 = 3'b001;
parameter SA2 = 3'b010;
parameter SA3 = 3'b011;
parameter SD0 = 3'b100;
parameter SD1 = 3'b101;
//state machine 2
parameter SR0 = 2'b00;
parameter SR1 = 2'b01;
parameter SR2 = 2'b10;
parameter SR3 = 2'b11;
//pmod als registers
//reg sclk; //2.5Mhz clk
//reg cs_n; //
reg [14:0] data_reg;
//count registers
//reg [5:0] cnt;
reg [15:0] cnt_d;
reg [5:0] cnt_r;
//state registers
reg [2:0] state_sclk;
reg [1:0] state_data;
//State Machine 1
always # (posedge clk)begin
if(reset_n == 1'b0)begin
cs_n <= 1'b1;
sclk <= 0;
cnt <= 6'd0;
cnt_d <= 16'd0;
end
else
case(state_sclk)
SA0:begin
sclk <= 1'b1;
state_sclk <= SA1;
if (cnt <= 6'd17)
cs_n <= 1'b0;
else
cs_n <= 1'b1;
end
SA1:begin
state_sclk <= SA2;
end
SA2:begin
sclk <= 1'b0;
cnt <= cnt + 1;
state_sclk <= SA3;
end
SA3:begin
if(cnt == 6'd21)begin
cnt <= 0;
state_sclk <= SD0;
end
else
state_sclk <= SA0;
end
SD0:begin
cnt_d <= delay;
state_sclk <= SD1;
end
SD1:begin
if (cnt_d == 0)
state_sclk <= SA0;
else
cnt_d <= cnt_d - 1;
end
default:begin
state_sclk <= SA0;
end
endcase
end
always # (posedge clk)begin
if (reset_n == 1'b0)begin
cnt_r <= 0;
data_reg <= 0;
end
else begin
case (state_data)
SR0:begin
if (cs_n == 1'b1 && sclk == 1'b1)
state_data <= SR1;
end
SR1: begin
if (cs_n == 1'b1)begin
state_data <= SR0;
cnt_r <= 0;
end
else if (sclk == 1'b0)
state_data <= SR2;
end
SR2:begin
if (cs_n == 1'b1)begin
state_data <= SR0;
cnt_r <= 0;
end
else if (cnt_r == 15)
state_data <= SR3;
else if (sclk == 1'b1)begin
data_reg [14-cnt_r] <= datain;
cnt_r <= cnt_r + 1;
state_data <= SR1;
end
end
SR3:begin
if (cs_n == 1) begin
Cout <= data_reg [11:8];
Dout <= data_reg [7:4];
state_data <= SR0;
end
end
default:begin
state_data <= SR0;
end
endcase
end
end
endmodule
I tried to make a simulation of it and the simulation indicates that after my cnt register reaches 15 it just cuts out and goes to 0.
simulation
That behavior is caused by your SA3 state.
SA3:begin
if(cnt == 6'd21)begin
cnt <= 0;
state_sclk <= SD0;
end
else
state_sclk <= SA0;
end
end
When your cnt == 6'd21 (which is 6'h15) the cnt is set to zero.
The generic variable names and lack of comments makes it difficult to see why this is not the expected behavior.
I don't know what is wrong in my code. Refer to the /* status */ comment near the full and empty logic.
I have write pointer wrapping around catching up with read pointer, then wr_addr[3] == ~rd_addr[3] and wr_addr[2:0] == rd_addr[2:0], I have a full condition.
I have read pointer catching up with write pointer, then wr_addr[3:0] == rd_addr[3:0], I have empty.
Please check my code and give me some advice.
I also provide the code on edaplayground (for those of you who have an account there).
module fifo(input clk, rst,
input wr, rd,
input [3:0] din,
output logic [3:0] dout,
output fifo_full, fifo_empty
);
logic [3:0] w_ptr, r_ptr;
logic w_en, r_en;
status_pointer ptr(clk, rst, wr, rd, w_en, r_en, w_ptr, r_ptr, fifo_full, fifo_empty);
memory mem(clk, w_en, r_en, w_ptr, r_ptr, din, dout);
endmodule
module memory(input clk, we, oe,
input [3:0] w_ptr, r_ptr,
input [3:0] din,
output logic [3:0] dout
);
logic [3:0] mem [7:0];
always_ff #(posedge clk) begin
if(we & (~ oe)) begin
mem[w_ptr[2:0]] <= din;
end
else if((~ we) & oe) begin
dout <= mem[r_ptr[2:0]];
end
else if(we & oe) begin
mem[w_ptr[3:0]] <= din;
dout <= mem[r_ptr[2:0]];
end
end
endmodule
module status_pointer(input clk, rst,
input wr, rd,
output w_en, r_en,
output logic [3:0] w_ptr, r_ptr,
output logic fifo_full, fifo_empty
);
/* status */
always #(posedge clk) begin
if(rst) begin
fifo_full <= 0;
fifo_empty <= 0;
end
else begin
if(w_ptr[2:0] == r_ptr[2:0]) begin
if(w_ptr[3] == r_ptr[3])
fifo_empty <= 1;
else
fifo_full <= 1;
end
else begin
fifo_full <= fifo_full;
fifo_empty <= 0;
end
end
end
/* pointer */
assign w_en = (fifo_full == 0) & wr;
assign r_en = (fifo_empty == 0) & rd;
always_ff #(posedge clk, posedge rst) begin
if(rst) begin
w_ptr <= 4'b0;
r_ptr <= 4'b0;
end
else if(w_en & (!r_en)) begin
w_ptr <= w_ptr + 4'b001;
end
else if(r_en & (!w_en)) begin
r_ptr <= r_ptr + 4'b001;
end
else if(w_en & r_en) begin
w_ptr <= w_ptr + 4'b001;
r_ptr <= r_ptr + 4'b001;
end
else begin
w_ptr <= w_ptr;
r_ptr <= r_ptr;
end
end
endmodule
//// test bench ////
module tb_fifo();
logic clk, rst, wr, rd;
logic [3:0] din, dout;
logic fifo_full, fifo_empty;
logic [4:0] counter;
fifo dut_fifo(clk, rst, wr, rd, din, dout, fifo_full, fifo_empty);
always begin
clk = 1; #4;
clk = 0; #4;
end
initial begin
counter = 5'b00000;
rst = 0; #240; rst = 1;
end
always #(posedge clk) begin
if(~ rst) begin
counter <= counter + 5'b00001;
if(counter == 5'b00000) begin
wr = 1; rd = 0; din = counter[3:0];
end
else if(counter == 5'b00001) begin
wr = 1; rd = 1; din = counter[3:0];
end
else if(counter == 5'b00010) begin
wr = 0; rd = 1; din = counter[3:0];
end
else if(counter == 5'b00011) begin
wr = 1; rd = 1; din = counter[3:0];
end
else if(counter == 5'b00100) begin // [3]
wr = 1; rd = 0; din = counter[3:0];
end
else if(counter == 5'b00101) begin // [3]
wr = 1; rd = 0; din = counter[3:0];
end
else if(counter == 5'b00110) begin // [3]
wr = 1; rd = 1; din = counter[3:0];
end
else if(counter == 5'b00111) begin // [3]
wr = 1; rd = 1; din = counter[3:0];
end
else if(counter == 5'b01000) begin // [3]
wr = 1; rd = 1; din = counter[3:0];
end
else if(counter == 5'b01001) begin // [3]
wr = 0; rd = 1; din = counter[3:0];
end
else if(counter == 5'b01010) begin // [3]
wr = 0; rd = 1; din = counter[4:1];
end
else if(counter == 5'b01011) begin // [3]
wr = 1; rd = 1; din = counter[3:0];
end
else if(counter == 5'b01100) begin // [3]
wr = 1; rd = 1; din = counter[4:1];
end
else if(counter == 5'b01101) begin // [3]
wr = 0; rd = 1; din = counter[3:0];
end
else if(counter == 5'b01110) begin // [3]
wr = 0; rd = 1; din = counter[3:0];
end
else if(counter == 5'b01111) begin // [3]
wr = 1; rd = 0; din = counter[3:0];
end
else if(counter == 5'b11111) begin
$stop;
end
else begin
wr = 0; rd = 0;
end
end
else begin
counter <= 5'b00000;
wr = 0; rd = 0;
end
end
endmodule
There is a problem in your testbench. Your design expects an active-high reset. You need to drive rst high starting at time 0 to reset the design, then drop it low after a delay. Just invert how you drive rst. Change:
rst = 0; #240; rst = 1;
to:
rst = 1; #240; rst = 0;
module FiniteStateMachine(output reg [2:0] Count, input clock, reset);
reg[2:0] state, next_state;
parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101, S6 = 3'b110, S7 = 3'b111;
always # (posedge clock, negedge reset)
if(reset==0) state<=S0;
else state <= next_state;
always # (state)
case(state)
S0: begin
Count = S0;
next_state = S1;
end
S1: begin
Count = S1;
next_state = S2;
end
S2: begin
Count = S3;
next_state = S3;
end
S3: begin
Count = S7;
next_state = S4:
end
S4: begin
Count = S6;
next_state = S5;
end
S5: begin
Count = S4;
next_state = S0;
end
endcase
endmodule
Getting the error:
Syntax in assignment statement l-value
I've also tried "<=" instead of "=" for all the assignments in case, but I'm getting the same error.
You used a colon instead of a semicolon. Change:
next_state = S4:
to:
next_state = S4;
I make a design for an adder but the result is wrong.
module FMUL(CLK, St, F1, E1, F2, E2, F, V, done);
input CLK;
input St;
input [3:0] F1;
input [3:0] E1;
input [3:0] F2;
input [3:0] E2;
output[6:0] F;
output V;
output done;
reg[6:0] F;
reg done;
reg V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
initial
begin
State = 0;
PS1 = 0;
NS1 = 0;
Nextstate=0;
end
always #(PS1 or St or Mdone or X or A or B)
begin : main_control
Load = 1'b0;
Adx = 1'b0;
NS1 = 0;
SM8 = 1'b0;
RSF = 1'b0;
LSF = 1'b0;
V = 1'b0;
F = 7'b0000000;
done = 1'b0;
case (PS1)
0 :
begin
F = 7'b0000000;
done = 1'b0;
V = 1'b0;
if(St == 1'b1)
begin
Load = 1'b1;
NS1 = 1;
end
end
1 :
begin
Adx = 1'b1;
NS1 = 2;
end
2 :
begin
if(Mdone == 1'b1)
begin
if(A==0)
begin
SM8 = 1'b1;
end
else if(A == 4 & B == 0)
begin
RSF = 1'b1;
end
else if (A[2] == A[1])
begin
LSF = 1'b1;
end
NS1 = 3;
end
else
begin
NS1 = 2;
end
end
3 : begin
if(X[4] != X[3])
begin
V = 1'b1;
end
else
begin
V = 1'b0;
end
done = 1'b1;
F = {A[2:0],B};
if(St==1'b0)
begin
NS1 = 0;
end
end
endcase
end
always #(State or Adx or B)
begin : mul2c
AdSh = 1'b0;
Sh = 1'b0;
Cm = 1'b0;
Mdone = 1'b0;
Nextstate = 0;
case(State)
0 :
begin
if(Adx==1'b1)
begin
if((B[0]) == 1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 1;
end
end
1,2 :
begin
if((B[0])==1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = State + 1;
end
3:
begin
if((B[0])==1'b1)
begin
Cm = 1'b1;
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 4;
end
4:
begin
Mdone = 1'b1;
Nextstate = 0;
end
endcase
end
wire [3:0] addout;
assign addout = (Cm == 1'b0)? (A+C) : (A-C);
always #(posedge CLK)
begin : update
PS1 <= NS1;
State <= Nextstate;
if(Load == 1'b1)
begin
X <= {E1[3], E1};
Y <= {E2[3], E2};
A <= 4'b0000;
B <= F1;
C <= F2;
end
if(Adx == 1'b1)
begin
X <= X+Y;
end
if(SM8 == 1'b1)
begin
X <= 5'b11000;
end
if(RSF == 1'b1)
begin
A <= {1'b0, A[3:1]};
B <= {A[0], B[3:1]};
X <= X+1;
end
if(LSF == 1'b1)
begin
A <= {A[2:0], B[3]};
B <= {B[2:0], 1'b0};
X <= X+31;
end
if(AdSh == 1'b1)
begin
A <= {(C[3]^Cm), addout[3:1]};
B <= {addout[0], B[3:1]};
end
if(Sh == 1'b1)
begin
A <= {A[3], A[3:1]};
B <= {A[0], B[3:1]};
end
end
endmodule
test bench.
module tb_FMUL();
wire[6:0] F;
wire done;
wire V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
reg CLK;
reg St;
reg [3:0] F1;
reg [3:0] E1;
reg [3:0] F2;
reg [3:0] E2;
FMUL u0(CLK, St, F1, E1, F2, E2, F, V, done);
always
begin
#10 CLK <= ~CLK;
end
initial
begin
#100 F1 = 2.125;
E1 = 5; F2 = 5.1; E2 = 1; St=0;
#100 F1 = 1.125;
E1 = 5; F2 = 2.1; E2 = 2; St=0;
#100 F1 = 5.125;
E1 = 5; F2 = 3.1; E2 = 3; St=0;
end
endmodule
The simulation results waveform.
enter image description here
I refer to the book.There is no code test bench.
So I made. But did't operate.
also CLK not is not changed.
please review the testbench code.
You have (at least) two problems:
Your clock needs to be initialised (eg to 1'b0):
initial CLK = 1'b0;
The initial value of any wire or reg in Verilog is 1'bx; ~1'bx is 1'bx; so CLK remains at 1'bx.
Your simulation doesn't stop. I added a call to $finish in the main initial block.
https://www.edaplayground.com/x/r4U
I am trying to design a fsm for showing rotational which runs the 4-digit 7-segment LED display unit, to cause a rotating pattern of circulating squares in clockwise or counterclockwise. I am trying to fix the syntax errors in my case block but I am in verilog coding and I cannot find my mistake. Here is the code:
module fsm( EN, CW, clk, AN1,AN2,AN3,AN4, leds );
//inputs and outputs
input EN, CW, clk;
output AN1,AN2,AN3,AN4;
output reg leds[6:0];
//state register and parameters
reg state[3:0];
parameter s0 = 3'b000;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;
parameter s6 = 3'b110;
parameter s7 = 3'b111;
//states and outputs according to the states
always # (posedge clk)
begin
if (EN == 1)
begin
case(state)
s0: leds<=7'b1100011; if(CW)begin state <= s1; end else begin state <= s7; end
s1: leds<=7'b1100011; if(CW)begin state <= s2; end else begin state <= s0; end
s2: leds<=7'b1100011; if(CW)begin state <= s3; end else begin state <= s1; end
s3: leds<=7'b1100011; if(CW)begin state <= s4; end else begin state <= s2; end
s4: leds<=7'b1011100; if(CW)begin state <= s5; end else begin state <= s3; end
s5: leds<=7'b1011100; if(CW)begin state <= s6; end else begin state <= s4; end
s6: leds<=7'b1011100; if(CW)begin state <= s7; end else begin state <= s5; end
s7: leds<=7'b1011100; if(CW)begin state <= s0; end else begin state <= s6; end
endcase
end
end
//output logic
assign AN1 = ~((state == s0) | (state == s7));
assign AN2 = ~((state == s1) | (state == s6));
assign AN3 = ~((state == s2) | (state == s5));
assign AN4 = ~((state == s3) | (state == s4));
endmodule
A few things.
You should declare your vector signals like this:
output reg [6:0] leds;
//state register and parameters
reg [3:0] state;
And, you need to wrap each case item with a begin/end. I also spread the statements across a few lines, which might make it more readable:
s0: begin
leds <= 7'b1100011;
if (CW) begin
state <= s1;
end else begin
state <= s7;
end
end
Or, you could replace the if/else with a ternary:
s0: begin
leds <= 7'b1100011;
state <= (CW) ? s1 : s7;
end