为输入二进制数计算 1 的 VERILOG 设计不断给我结果 1 而不是正确的计数

问题描述 投票:0回答:1

EDA 游乐场链接:https://edaplayground.com/x/PQVx

这是这个算法的状态表

有人可以帮我调试这个 verilog 设计吗?我检查了我的逻辑并检查了所有内容。然而,EDA playground 的模拟总是给我 count = 1 的每种情况。此外,只计算了 Testvector.txt 的前两行,EDA playground 给我一个错误:

警告:testbench.sv:24: $readmemb: 标准不一致,如下 1364-2005.

警告:testbench.sv:24: $readmemb(Testvector.txt): 中的单词太多 请求范围 [0:3] 的文件。

下面附上设计代码和测试台文件:

设计文件:

   //top module
module GDP(count, start, restart, clk, n, done);

//top module combines all other modules, including DP and CU
// Note: nEqZero is the input N=0, that is false condition is //evaluated, just for the convenience
    
input start, clk, restart;
    input [7:0] n;
    output [7:0] count;
    output done;
    
    wire WE, RAE, RBE, OE, nEqZero, LSB, IE;
    wire [1:0] WA, RAA, RBA, SH;
    wire [2:0] ALU;
    
    //instantiate control unit
    CU control (IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE, ~start, clk, ~restart, nEqZero, LSB);

    //instantiate datapath
    DP datapath (nEqZero, LSB, count, n, clk, IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE);
    
    assign done = OE;
endmodule

module CU(IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE, start, clk, restart, nEqZero, LSB);

    input start, clk, restart;
    output IE, WE, RAE, RBE, OE;
    output [1:0] WA, RAA, RBA, SH;
    output [2:0] ALU;
    
    input wire nEqZero;
    input wire LSB;
    reg [2:0] state;
    reg [2:0] nextstate;

    parameter S0 = 3'b000; 
    parameter S1 = 3'b001;
    parameter S2 = 3'b010;
    parameter S3 = 3'b011;
    parameter S4 = 3'b100;
    
    initial
    state = S0;
    
    // State register
    always @ (posedge clk)
    begin
        state <= nextstate;
    end
    // NS logic
    always @ (*)
        case(state)
            S0:if(start) nextstate = S1;//at s0, if start is true, go to s1
                else    nextstate = S0;//otherwise stay at s0
                S1:if(~nEqZero && LSB) nextstate = S2;//if N ~= 0  and LSB = 1, count++
                S1:if(~nEqZero && ~LSB) nextstate = S3;//if N ~= 0  and LSB=0, n>>
                S1:if(nEqZero) nextstate = S4;//if N = 0, go to output
            S2:nextstate = S3;//after count++,n>>
            S3:if(nEqZero) nextstate = S4;//after N>>, if n=0, output
            S3:if(~nEqZero && LSB) nextstate = S2;//otherwise, back to S2 and check for LSB
                S3:if(~nEqZero && ~LSB) nextstate = S3;
            S4:if(restart) nextstate = S0;//at s4, if restart is true, back to s0
                else   nextstate = S4;//otherwise no change
            default: nextstate = S0;//initial state is s0
        endcase
        
    // output logic
    assign IE = state==S1; 
    assign WE = (state == S0) || (state == S1)||(state == S2)||(state==S3);
    assign WA[1] = 0;
    assign WA[0] = (state == S1)||(state == S3);
    assign RAE = (state == S0) || (state ==S2) || (state == S3)||(state == S4);
    assign RAA[1] = 0;
    assign RAA[0] = state == S3;
        
    assign RBE = state == S0;
    assign RBA[1] = 0;
    assign RBA[0] = 0;
        
    assign ALU[2] = state== S0|| state==S2;
    assign ALU[1] = state == S2;
    assign ALU[0] = state == S0; 
    assign SH[1] = state == S3;
    assign SH[0] = 0;
    assign OE = state == S4;
        
endmodule

module DP(nEQZero, LSB, count, nIn, clk, IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE);

    input clk, IE, WE, RAE, RBE, OE;
    input [1:0] WA, RAA, RBA, SH;
    input [2:0] ALU;
    input [7:0] nIn;
    
    output nEQZero;
    output LSB;
    output wire [7:0] count;
    
    reg [7:0] rfIn;
    wire [7:0] RFa, RFb, aluOut, shOut, n;
    
     initial 
     rfIn = 0;
     
    always @ (*)
        rfIn = n;
    
    mux8 muxs (n, shOut, nIn, IE);
    Regfile RF (clk, RAA, RFa, RBA, RFb, WE, WA, rfIn, RAE, RBE);
    alu theALU (aluOut, RFa, RFb, ALU);
    shifter SHIFT (shOut, aluOut, SH);
    buff buffer1 (count, shOut, OE);
    
    assign nEQZero = n == 0;  //note: checks the false condition
    assign LSB = n[0] == 1; //note: checks the false condition
    
endmodule
// ALU
module alu (out,a,b,sel);
    input [7:0] a,b;
    input [2:0] sel; 
    output [7:0] out;
    reg [7:0] out;

    always @ (*) 
    begin 
        case(sel) 
            3'b000: out=a;                  
            3'b001: out=a&b;                  
            3'b010: out=a|b;                  
            3'b011: out=!a;                  
            3'b100: out=a+b;                  
            3'b101: out=a-b;     
            3'b110: out=a+1;                 
            3'b111: out=a-1;                  
        endcase
    end
endmodule
// final buffer
module buff(output reg [7:0] result, input[7:0] a, input buf1);
    always @(*)
        if(buf1 == 1)
            result = a;
        else 
            result = 8'bzzzz_zzzz;      
endmodule
// 2-to-1 mux (sel = 0 -> choose a)
module mux8(result, a, b, sel);

    output reg[7:0] result;
    input[7:0] a;
    input[7:0] b;
    input sel;
    
    always @(*)
        if(sel == 0)
            result = a;
        else
            result = b;
            
endmodule
// Regfile for GDP
module Regfile(
                    input clk,
                    input   [1:0]  RAA, // Port A Read address 
                    output  [7:0] ReadA,   // Port A
                    input   [1:0] RBA,   // Port B Read address 
                    output  [7:0] ReadB,   // Port B
                    input   WE,    // Write enable 
                    input   [1:0] WA,  // Write port register address
                    input   [7:0] INPUT_D,  // Write data port
                    input   RAE,  // Port A decoder enable
                    input   RBE // Port B decoder enable

                    ); 
            // width          depth
            reg [7:0]  REG_F [0:3];

// Write only when WE is asserted

always @(posedge clk) 
if (WE == 1)  REG_F[WA] <= INPUT_D;
     
  //reading to Port A and B, combinational
  assign ReadA = (RAE)? REG_F [RAA]:0; 
  assign ReadB = (RBE)? REG_F [RBA]:0;
          
endmodule
// Shifter
module shifter (out,a,sh);
    input [7:0] a;
    input [1:0] sh;
    output reg [7:0] out;

    always @ (*) 
    begin 
        case(sh) 
            3'b00: out=a;                  
            3'b01: out=a << 1;                  
            3'b10: out=a >> 1;                  
            3'b11: out={a[6],a[5],a[4],a[3],a[2],a[1],a[0], a[7]} ;
        endcase
    end
endmodule

测试台文件:


module testb1;
    parameter vectlength = 4;
    wire displayRes;
    wire [7:0] count;
    reg [7:0] nIn;
    reg [3:0] count_exp;
    reg [11:0] vect[3:0];
    reg start, restart, clk;

    integer i;
    
    initial
    begin
        i = 0;
        $readmemb("Testvector.txt", vect);
      
        start = 1;
        restart = 1;
        clk = 0;
        // Clock generator 
        forever
          #2 clk = ~clk;  
    end
    

    //start the algorithm
    always @ (posedge clk)
        begin
          #1;{nIn,count_exp}=vect[i];//parse the testvector to input A and expected result count_exp
        end
    
    always @ (negedge clk)
    begin
        for(i = 0; i < vectlength; i = i + 1) 
        begin
            start = 0;
            #40 restart = 1;
            // Waiting for the work to finish, DispRes (Done)=1
            while(displayRes !=1 && nIn[0]==1)
                #5 begin end
                $write("Input: %2d, Result:%3d,Expected:         %3d:",nIn,count,count_exp);
            
        if(count == count_exp)
                    $display("Correct!");
            else
                    $display("Incorrect!");
            
            restart = 0;
            start = 1;
            
        end
        
        $stop;
    end
      
//Initialize GDP    
GDP main (    count, 
              start, 
              restart, 
              clk, 
              nIn,
              displayRes);
endmodule

测试向量.txt


11010101_0101

11000001_0011

00000000_0000

10101010_0100

11111111_1000

verilog hdl
1个回答
0
投票

解决自述消息。
这些消息是警告,而不是错误。
如果您了解它们,并且喜欢代码本身的行为,那么您就很好。

第一个警告是说代码违反了定义与 readmemb 关联的内存变量的默认样式。
这与方向有关。
你这样定义变量:

reg [vectwidth-1:0] vect[vectlength-1:0];

这样定义它,警告消失了:

reg [vectwidth-1:0] vect[0:vectlength-1];    

第二个警告与向量的数量有关。
您在文本文件中有 5 行数据,以及一个包含 4 个位置的数组以将它们放入您的内存变量中。

parameter vectlength = 4;    

将此更改为 5,警告消失。

© www.soinside.com 2019 - 2024. All rights reserved.