I am implementing a One's Counter that will count for the number of ones of an 8-bit binary value.
S0:
start
=0
↓
S1:R1
=Inport
↓
S2:R3
=0
↓
S3:R2
=1
↓
S4:R4
=R1
AND
R2
↓
S5:R3
=R3
+R4
↓
S6:R1
=R1
>>
1
→ S4 (ifZ
=0
)
↓
S7:Outport
=R3
,
done
=1
(ifZ
=1
)
↓
S0
Data := Inport
Ocount := 0
Mask := 1
while Data is not 0 repeat
Temp := Data AND Mask
Ocount := Ocount + Temp
Data := Data >> 1
end while
Outport := Ocount
↓
R1 := Inport
R3 := 0
R2 := 1
while ~Z repeat
R4 := R1 AND R2
R3 := R3 + R4
R1 := R1 >> 1
end while
Outport := R3
I want to implement Ones Counter using Verilog Structural Level Modeling.
Below are my code
, testbench
, and the visualized result
(with lots of debugging details in it):
module Mux(A,B,S,Y, muxa, muxb, y);
input [7:0] A,B;
input S;
output [7:0] Y;
reg [7:0] Y;
output [7:0] muxa, muxb, y;
assign muxa = A;
assign muxb = B;
assign y = Y;
always@(A or B or S)
begin
case(S)
1'b0: Y = A;
1'b1: Y = B;
endcase
end
endmodule
module Regfile(WA,WE,RAA,REA,RAB,REB,DATA_W,DATA_A,DATA_B,clk,rst);
input [2:0] WA, RAA, RAB; // WriteAddress, ReadAddressA, ReadAddressB
input WE, REA, REB, clk, rst; // WriteEnable, ReadEnableA, ReadEnableB, clock, reset
input [7:0] DATA_W;
output [7:0] DATA_A, DATA_B;
wire [7:0] DATA_A, DATA_B;
reg [7:0] registers[7:0];
assign DATA_A = REA? registers[RAA]:8'bz;
assign DATA_B = REB? registers[RAB]:8'bz;
always@(posedge clk, negedge rst)
begin
if(~rst) registers[0] <= 1'b0;
else
begin
if(WE) registers[WA] <= DATA_W;
end
end
endmodule
module ALU(A,B,sel,F, a, b);
input [7:0] A,B;
input [2:0] sel;
output [7:0] F;
reg [7:0] F;
output [7:0] a,b;
assign a = A;
assign b = B;
always@(sel or A or B)
begin
case(sel)
3'b000: F = ~A; // complement A
3'b001: F = A & B; // and
3'b010: F = A ^ B; // xor
3'b011: F = A | B; // or
3'b100: F = A - 1; // decrement A
3'b101: F = A + B; // add
3'b110: F = A - B; // subtract
3'b111: F = A + 1; // increment A
endcase
end
endmodule
module Shifter(Data_in, SR, Data_out);
input [7:0] Data_in;
input SR;
output [7:0] Data_out;
reg [7:0] Data_out;
always@(Data_in or SR)
begin
if(SR==1'b1) Data_out <= {1'b0, Data_in[7:1]};
else Data_out <= Data_in;
end
endmodule
module Controller(start, Z, clk, rst, ctrl, done, curState);
input start, Z, clk, rst;
output done;
output [17:0] ctrl;
reg done;
reg [17:0] ctrl;
reg [2:0] Current_State, Next_State;
parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011;
parameter S4 = 3'b100, S5 = 3'b101, S6 = 3'b110, S7 = 3'b111;
output [2:0] curState;
always@(posedge clk, negedge rst)
if(~rst) Current_State <= S0;
else Current_State <= Next_State;
assign curState = Current_State;
always@(start or Z or Current_State)
begin
case(Current_State)
S0:
begin
ctrl = 18'b0_0000_0000_0000_000_00;
done = 1'b0;
if(~start) Next_State = S0;
else Next_State = S1;
end
S1:
begin
ctrl = 18'b1_0011_0000_0000_000_00;
done = 1'b0;
Next_State = S2;
end
S2:
begin
ctrl = 18'b0_0111_0001_0001_101_00;
done = 1'b0;
Next_State = S3;
end
S3:
begin
ctrl = 18'b0_0101_0001_0000_111_00;
done = 1'b0;
Next_State = S4;
end
S4:
begin
ctrl = 18'b0_1001_0011_0101_001_00;
done = 1'b0;
Next_State = S5;
end
S5:
begin
ctrl = 18'b0_0111_0111_1001_101_00;
done = 1'b0;
Next_State = S6;
end
S6:
begin
ctrl = 18'b0_0011_0011_0001_101_10;
done = 1'b0;
if(Z) Next_State = S7;
else Next_State = S4;
end
S7:
begin
ctrl = 18'b0_0000_0111_0001_101_01;
done = 1'b1;
Next_State = S0;
end
endcase
end
endmodule
module DataPath(Inport, ctrl, clk, rst, Outport, Z, bsf, di, a , b, muxa, muxb, y);
input [7:0] Inport;
input [17:0] ctrl;
input clk, rst;
output [7:0] Outport;
output Z;
wire [7:0] B_M, B_RA, B_RB, B_ALU, B_SF;
output [7:0] bsf, di, a, b, muxa, muxb, y;
Mux mux(.A(B_SF), .B(Inport), .S(ctrl[17]), .Y(B_M), .muxa(muxa), .muxb(muxb), .y(y));
Regfile regfile(.WA(ctrl[16:14]), .WE(ctrl[13]), .RAA(ctrl[12:10]), .REA(ctrl[9]), .RAB(ctrl[8:6]), .REB(ctrl[5]), .DATA_W(B_M), .DATA_A(B_RA), .DATA_B(B_RB), .clk(clk), .rst(rst));
ALU alu(.A(B_RA), .B(B_RB), .sel(ctrl[4:2]), .F(B_ALU), .a(a), .b(b));
Shifter shifter(.Data_in(B_ALU), .SR(ctrl[1]), .Data_out(B_SF));
assign Outport = ctrl[0]? B_SF:8'bz;
assign Z = ~|B_SF;
assign di = B_ALU;
assign bsf = B_SF;
endmodule
module OnesCounter(start, Inport, clk, rst, Outport, done, curState, bsf, di, a, b, muxa, muxb, y);
input start, clk, rst;
input [7:0] Inport;
output done;
output [7:0] Outport;
output [2:0] curState;
wire Z;
wire [17:0] ctrl;
output [7:0] bsf, di, a, b, muxa, muxb, y;
Controller controller(.start(start), .Z(Z), .clk(clk), .rst(rst), .ctrl(ctrl), .done(done), .curState(curState));
DataPath dataPath(.Inport(Inport), .ctrl(ctrl), .clk(clk), .Outport(Outport), .Z(Z), .bsf(bsf), .di(di), .a(a), .b(b), .muxa(muxa), .muxb(muxb), .y(y));
endmodule
module testbench();
reg [7:0] Inport;
reg start, clk, rst;
wire [7:0] Outport;
wire done;
wire [2:0] curState;
wire [7:0] bsf, di, a, b, muxa, muxb, y;
OnesCounter test(.start(start), .Inport(Inport), .clk(clk), .rst(rst), .Outport(Outport), .done(done), .curState(curState), .bsf(bsf), .di(di), .a(a), .b(b), .muxa(muxa), .muxb(muxb), .y(y));
initial #400 $finish;
initial begin clk = 0; forever #5 clk = ~clk; end
initial fork
rst = 0;
start = 0;
#3 rst = 1;
#30 start = 1; Inport = 215; // 215 = 1101 0111
#40 start = 0;
join
endmodule
I think the problem is caused by the clock, but I have no idea how to fix it. It seems that the output values are all oscillating so most of them produce an X
as a result.
When I compile your code, I see this warning:
DataPath dataPath(.Inport(Inport), .ctrl(ctrl), .clk(clk), .Outport(Outport), .Z(Z), .bsf(bsf), .di(di), .a(a), .b(b), .muxa(muxa), .muxb(muxb), .y(y));
|
xmelab: *W,CUVWSI : 1 input port was not connected:
xmelab: rst
If your simulator does not generate a warning, you can try your code on other simulators on the EDA Playground site.
To fix the warning, you need to connect the rst
signal to the dataPath
instance. Change:
DataPath dataPath(.Inport(Inport), .ctrl(ctrl), .clk(clk), .Outport(Outport), .Z(Z), .bsf(bsf), .di(di), .a(a), .b(b), .muxa(muxa), .muxb(muxb), .y(y));
to:
DataPath dataPath(.rst(rst), .Inport(Inport), .ctrl(ctrl), .clk(clk), .Outport(Outport), .Z(Z), .bsf(bsf), .di(di), .a(a), .b(b), .muxa(muxa), .muxb(muxb), .y(y));
This clears up a lot of the unknowns (x's).