代码之家  ›  专栏  ›  技术社区  ›  John

使用结构级建模设计一个计数器(已解决问题)

  •  1
  • John  · 技术社区  · 2 年前

    Ones Counter Implement(结构级建模)

    我正在实现一个“一个计数器”,它将计算8位二进制值的“一”个数。

    状态图

    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 (如果 Z = 0 )

    S7 : Outport = R3 ,
    done = 1. (如果 Z = 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
    

    我想实施 一个计数器 使用Verilog结构级建模。
    下面是我的 code , testbench ,以及可视化的 result (其中包含许多调试细节):

    解释

    流程如下

    enter image description here

    密码

    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
    

    可视化结果

    enter image description here

    我的假设

    我认为问题是由时钟引起的,但我不知道如何解决。似乎输出值都在振荡,所以大多数输出值都会产生 X 因此

    问题是什么!

    问题解决了!出现此错误是因为我忘记了需要放入“DataPath”模块中的“rst”参数,该参数位于第208行的“OnesCounter”模块中。修改这行代码后,代码工作正常!我将把我的代码留在这里,供任何可能有相关问题的人参考。再次感谢大家
    1 回复  |  直到 2 年前
        1
  •  1
  •   toolic    2 年前

    当我编译您的代码时,我会看到以下警告:

        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
    

    如果你的模拟器没有生成警告,你可以在EDA Playground网站上的其他模拟器上尝试你的代码。

    若要修复警告,您需要连接 rst 的信号 dataPath 例子更改:

    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));
    

    至:

    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));
    

    这就清除了许多未知因素。