繁体   English   中英

Verilog DUT系统Verilog测试台:输出到接线分配1s替换为Xs

Verilog DUT System Verilog testbench: output to wire assignment 1s replaced with Xs

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我在System Verilog中有一个Modelsim测试台,其中测试了Verilog顶层模块( ufm1 )和内部使用的另一个Verilog模块( wishbone ),还有一个系统Verilog“ stub”( wishbone_sim )已连接到测试台中的DUT 。

DUT和内部模块最初在System Verilog中使用,并且工作正常,但是我必须将它们转换为Verilog才能使用Diamond LSE(将测试台留在System Verilog中)

DUT内部的内部模块有一个输出,我将其连接到DUT内部的wire (最初是System Verilog版本中的reg ,因为否则会产生错误),然后使用电线将其分配给程序中的reg阻止DUT内部。

在内部模块内部,基本上从输入直接分配此输出。

现在,当我对此进行仿真时,内部模块中的输入很好,但是输出(应该是相同的,因为它是直接assign )应该是不同的,用Xs代替1s。

仅在将内部模块( rd_data )的输出分配给电线( wb_rd_data )时,此问题才开始出现,这看起来很奇怪,因为我看不到将输出端口连接到电线会如何影响其值。

该DUT内的导线是wb_rd_data至极连接到rd_data内的端口wishbone模块。

我该如何解决?

被测设备:

module ufm1(clk, ufm_wr_rq, ufm_rd_rq, ufm_wr_data, ufm_wr_ack, ufm_rd_data, ufm_rd_ack, ufm_done, wb_clk, wb_rst, wb_cyc, wb_stb, wb_we, wb_addr, wb_dat_i, wb_dat_o, wb_ack);

input clk;
input ufm_wr_rq, ufm_rd_rq;
input [7:0] ufm_wr_data;
output reg ufm_wr_ack;
output [7:0] ufm_rd_data;
output ufm_rd_ack;
output reg ufm_done = 0;

output wb_clk;
output wb_rst;
output wb_cyc;
output wb_stb;
output wb_we;
output [7:0] wb_addr;
output [7:0] wb_dat_i;
input [7:0] wb_dat_o;
input wb_ack;

      parameter WR_OF = 8'h10;
      parameter WR_CF = 8'h11;
      parameter WR = 8'h12;
      parameter WRE = 8'h13;
      parameter RD = 8'h20;
      parameter RDI = 8'h21;
      parameter JMPI = 8'h30;
      parameter END = 8'h40;

      parameter Z00 = 8'h00;
      parameter FF = 8'hFF;

      parameter WR_CMDS = 4'h1;
      parameter RD_CMDS = 4'h2;
      parameter JMP_CMDS = 4'h3;
      parameter END_CMDS = 4'h4;

      parameter CMD_EN_CFG_I = 8'h74;
      parameter CMD_DIS_CFG_I = 8'h26;
      parameter CMD_RD_ST = 8'h3C;
      parameter CMD_ZERO_ADDR = 8'h47;
      parameter CMD_RD_UFM = 8'hCA;
      parameter CMD_WR_UFM = 8'hC9;
      parameter CMD_ERASE_UFM = 8'hCB;
      parameter CMD_BYPASS = 8'hFF;

      parameter ST_IDL = 3'd0;
      parameter ST_NEXT_CMD = 3'd1;   
      parameter ST_WT_WR = 3'd2;
      parameter ST_WT_RD = 3'd3;

      parameter CMDS_NUM = 9'd196;
      parameter WR_PRG_START_INDEX = 9'd103;

      parameter [CMDS_NUM*8-1:0] CMDS = {
            //**** Erase and read
            //Enabled configuration interface
            WR_OF, WR, CMD_EN_CFG_I, WR, 8'h08, WR, Z00, WR, Z00, WR_CF,
            //Read config status register and repeat till not busy
            WR_OF, WR, CMD_RD_ST,    WR, Z00,   WR, Z00, WR, Z00, RD, RD, RD, WR_CF, JMPI,
            //Zero UFM address
            WR_OF, WR, CMD_ZERO_ADDR,WR, Z00,   WR, Z00, WR, Z00, WR_CF,
            //Read UFM page 0 (16 bytes) 
            WR_OF, WR, CMD_RD_UFM, WR,   Z00,   WR, Z00, WR, 8'h01,
            RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,RDI,
            WR_CF,
            //Erase UFM
            WR_OF, WR, CMD_ERASE_UFM,WR, Z00,   WR, Z00, WR, Z00, WR_CF,
            //Read config status register and repeat till not busy
            WR_OF, WR, CMD_RD_ST,    WR, Z00,   WR, Z00, WR, Z00, RD, RD, RD, WR_CF, JMPI, 
            //Disable configuration interface
            WR_OF, WR, CMD_DIS_CFG_I, WR, Z00, WR, Z00, WR_CF,
            //Bypass (NOP)
            WR_OF, WR, CMD_BYPASS,    WR, FF,  WR, FF,  WR,  FF, WR_CF,

            END,  

            //**** Write
            //Enabled configuration interface
            WR_OF, WR, CMD_EN_CFG_I, WR, 8'h08, WR, Z00, WR, Z00, WR_CF,
            //Read config status register and repeat till not busy
            WR_OF, WR, CMD_RD_ST,    WR, Z00,   WR, Z00, WR, Z00, RD, RD, RD, WR_CF, JMPI,
            //Zero UFM address
            WR_OF, WR, CMD_ZERO_ADDR,WR, Z00,   WR, Z00, WR, Z00, WR_CF,
            //Write UFM page 0 (16 bytes) 
            WR_OF, WR, CMD_WR_UFM, WR,   Z00,   WR, Z00, WR, 8'h01,
            WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,WRE,
            WR_CF,
            //Read config status register and repeat till not busy
            WR_OF, WR, CMD_RD_ST,    WR, Z00,   WR, Z00, WR, Z00, RD, RD, RD, WR_CF, JMPI, 
            //Disable configuration interface
            WR_OF, WR, CMD_DIS_CFG_I, WR, Z00, WR, Z00, WR_CF,
            //Bypass (NOP)
            WR_OF, WR, CMD_BYPASS,    WR, FF,  WR, FF,  WR,  FF, WR_CF,

            END  
      };



      reg wb_wr_rq = 0, wb_rd_rq = 0;
      reg [7:0] wb_wr_data = 0;
      wire [7:0] wb_rd_data = 0;
      reg [7:0] addr = 0;       

      wishbone wishbone(.clk(clk), .wr_rq(wb_wr_rq), .rd_rq(wb_rd_rq), .wr_data(wb_wr_data), .rd_data(wb_rd_data),
                        .addr(addr), .done(wb_done), .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_cyc(wb_cyc), .wb_stb(wb_stb),
                        .wb_we(wb_we), .wb_addr(wb_addr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o), .wb_ack(wb_ack));


      reg [2:0] st = 0;
      reg [2:0] prev_st = 0;
      reg [7:0] prev_cmd = 0;
      reg [CMDS_NUM*8-1:0] cmds = CMDS;
      reg [8:0] cmd_index = 0;
      reg [7:0] lst_rd_data = 0;

      wire [7:0] cur_cmd = cmds[((CMDS_NUM-cmd_index-1)*8)+:8];
      wire [7:0] next_cmd = cmds[((CMDS_NUM-cmd_index-2)*8)+:8];

      assign is_cmd_wre = (cur_cmd == WRE);
      assign is_1cmd_wr = (cur_cmd == WRE || cur_cmd == WR_OF || cur_cmd == WR_CF);

      assign ufm_rd_ack = (prev_st == ST_WT_RD) && (prev_cmd == RDI) && wb_done;
      assign ufm_rd_data = ufm_rd_ack ? wb_rd_data : 0;

      always @(posedge clk)
      begin

        prev_st <= st;
        prev_cmd <= cur_cmd;

        case(st)
          ST_IDL:
          begin
            ufm_done <= 0;
            if(ufm_rd_rq)
            begin            
              st <= ST_NEXT_CMD;
            end
            else
            if(ufm_wr_rq)
            begin
              st <= ST_NEXT_CMD;
              cmd_index <= WR_PRG_START_INDEX;
            end           
          end          
          ST_NEXT_CMD:           
            case(cur_cmd[7:4])
               WR_CMDS:
               begin
                 wb_wr_rq <= 1;
                 wb_wr_data <= (cur_cmd == WR_OF) ? 8'h80 :
                           (cur_cmd == WR_CF ? 8'h00 : (is_cmd_wre ? ufm_wr_data : next_cmd));
                 addr <= (cur_cmd == WR_OF || cur_cmd == WR_CF) ? 8'h70 : 8'h71;
                 ufm_wr_ack <= is_cmd_wre;                                   
                 st <= ST_WT_WR;
               end

               RD_CMDS:
               begin
                 wb_rd_rq <= 1;
                 addr <= 8'h73;
                 st <= ST_WT_RD;                  
               end

               JMP_CMDS:
               begin
                 st <= ST_NEXT_CMD;

                 if(lst_rd_data[4]) //if busy
                 begin
                   cmd_index <= cmd_index - 13; //assuming the previous command is reading the status register 
                 end
                 else
                 begin
                   cmd_index <= cmd_index + 1;
                 end
               end 

               END_CMDS:
               begin
                 st <= ST_IDL;
                 cmd_index <= 0;
                 ufm_done <= 1;
               end              
            endcase

          ST_WT_WR:
          begin
            wb_wr_rq <= 0;
            ufm_wr_ack <= 0;
            if(wb_done)
            begin
               wb_wr_data <= 0; //todo: not necessary, can be removed if doesn't fit
               cmd_index <= cmd_index + (is_1cmd_wr ? 1 : 2);
               st <= ST_NEXT_CMD;
            end
          end

          ST_WT_RD:
          begin
            wb_rd_rq <= 0;
            if(wb_done)
            begin              
              lst_rd_data <= wb_rd_data;
              cmd_index <= cmd_index + 1;
              st <= ST_NEXT_CMD; 
            end
          end         
        endcase
      end

endmodule

内部模块:

module wishbone(clk, wr_rq, rd_rq, done, addr, wr_data, rd_data, wb_clk, wb_rst, wb_cyc, wb_stb, wb_we, wb_addr, wb_dat_i, wb_dat_o, wb_ack);

input clk;
input wr_rq, rd_rq;
output done;
input [7:0] addr;
input [7:0] wr_data;
output [7:0] rd_data;


output wb_clk;
output wb_rst;
output wb_cyc;
output wb_stb;
output wb_we;
output [7:0] wb_addr;
output [7:0] wb_dat_i;
input [7:0] wb_dat_o;
input wb_ack;

reg wr_in_progress = 0;
reg rd_in_progress = 0;

assign done = wb_ack;
assign wb_clk = clk;
assign wb_addr = (wr_in_progress || rd_in_progress) ? addr : 0;
assign wb_dat_i = wr_in_progress ? wr_data : 0;
assign rd_data = wb_dat_o;
assign wb_rst = 0;
assign wb_cyc = wr_in_progress || rd_in_progress;
assign wb_stb = wb_cyc;
assign wb_we = wr_in_progress;

always @(posedge clk)
begin
    if(!wr_in_progress && !rd_in_progress)
    begin
         if(wr_rq)
         begin
            wr_in_progress <= 1;            
         end
         else if(rd_rq)
         begin
            rd_in_progress <= 1;
         end
    end
    else if(wr_in_progress && wb_ack)
    begin
         wr_in_progress <= 0;
    end
    else if(rd_in_progress && wb_ack)
    begin
         rd_in_progress <= 0;         
    end   
end

endmodule

试验台:

`timescale 100ps / 100ps

module ufm1_tb;

      parameter WR_OF = 8'h10;
      parameter WR_CF = 8'h11;
      parameter WR = 8'h12;
      parameter WRE = 8'h13;
      parameter RD = 8'h20;
      parameter RDI = 8'h21;
      parameter JMPI = 8'h30;
      parameter END = 8'h40;

      parameter Z00 = 8'h00;
      parameter FF = 8'hFF;

      parameter WR_CMDS = 4'h1;
      parameter RD_CMDS = 4'h2;
      parameter JMS_CMDS = 4'h3;

      parameter CMD_EN_CFG_I = 8'h74;
      parameter CMD_DIS_CFG_I = 8'h26;
      parameter CMD_RD_ST = 8'h3C;
      parameter CMD_ZERO_ADDR = 8'h47;
      parameter CMD_RD_UFM = 8'hCA;
      parameter CMD_WR_UFM = 8'hC9;
      parameter CMD_ERASE_UFM = 8'hCB;
      parameter CMD_BYPASS = 8'hFF;

parameter CD = 200; //100ps*200=20nS (50MHz)
parameter HCD = CD/2; 
parameter QCD = CD/4;

parameter IGNORE = 8'h00;
parameter BUSY = 8'h10;
parameter FREE = 8'h00;

parameter [7:0] DATA [] = '{
            //**** erase/read
            //First busy wait
            IGNORE, IGNORE, BUSY,
            IGNORE, IGNORE, FREE,
            //UFM Page 0 read
            8'hA0,8'hA1,8'hA2,8'hA3,8'hA4,8'hA5,8'hA6,8'hA7,8'hA8,8'hA9,8'hAA,8'hAB,8'hAC,8'hAD,8'hAE,8'hAF,
            //Second busy wait 
            IGNORE, IGNORE, BUSY,
            IGNORE, IGNORE, BUSY,
            IGNORE, IGNORE, FREE,

            //**** write
            //First busy wait
            IGNORE, IGNORE, BUSY,
            IGNORE, IGNORE, FREE,

            //Second busy wait 
            IGNORE, IGNORE, BUSY,
            IGNORE, IGNORE, BUSY,
            IGNORE, IGNORE, FREE 
      };

parameter [7:0] DELAYS [] = '{{dut.CMDS_NUM}{8'h0}};
parameter [7:0] WRDATA [] = '{8'hBF,8'hBE,8'hBD,8'hBC,8'hBB,8'hBA,8'hB9,8'hB8,8'hB7,8'hB6,8'hB5,8'hB4,8'hB3,8'hB2,8'hB1,8'hB0};

parameter ST_IDLE = 0;
parameter ST_READING = 1;
parameter ST_WRITING = 2;
parameter ST_FINISHED = 3;

reg clk = 0;

always #(HCD) clk = ~clk;

wishbone_sim
#(
  .CD(CD),
  .DATA(DATA),
  .NUM_OPERATIONS(dut.CMDS_NUM),
  .DELAYS('{{dut.CMDS_NUM}{0'h0}})
)
wb_sim(.wb_clk(dut.wb_clk), .wb_rst(dut.wb_rst), .wb_stb(dut.wb_stb), .wb_cyc(dut.wb_cyc), .wb_we(dut.wb_we), .wb_addr(dut.wb_addr), .wb_dat_i(dut.wb_dat_i), .wb_dat_o(dut.wb_dat_o), .wb_ack(dut.wb_ack));

reg ufm_wr_rq = 0;
reg ufm_rd_rq = 0;
reg [3:0] st = ST_IDLE;
reg [7:0] ufm_wr_data = 8'bZ;
reg [4:0] ufm_wr_data_idx = 0;

wire [7:0] ufm_rd_data;
wire [7:0] wb_addr;
wire [7:0] wb_dat_i;
wire [7:0] wb_dat_o;

ufm1 dut(clk, ufm_wr_rq, ufm_rd_rq, ufm_wr_data, ufm_wr_ack, ufm_rd_data, ufm_rd_ack, ufm_done,
         wb_clk, wb_rst, wb_cyc, wb_stb, wb_we, wb_addr, wb_dat_i, wb_dat_o, wb_ack);

always @(posedge clk)
begin
   case(st)
      ST_IDLE:
      begin
        ufm_rd_rq <= 1;
        st <= ST_READING;        
      end
      ST_READING:
      begin
        ufm_rd_rq <= 0;
        if(ufm_done)
        begin
          ufm_wr_rq <= 1;
          ufm_wr_data <= WRDATA[ufm_wr_data_idx];
          ufm_wr_data_idx <= ufm_wr_data_idx + 1;
          st <= ST_WRITING;
        end
      end
      ST_WRITING:
      begin
        ufm_wr_rq <= 0;
        if(ufm_wr_ack)
        begin
          ufm_wr_data <= WRDATA[ufm_wr_data_idx];
          ufm_wr_data_idx <= ufm_wr_data_idx + 1;
        end
        if(ufm_done) st <= ST_FINISHED;
      end
   endcase    
end

endmodule
1 个回复

问题是我在DUT中有wb_rd_data线的默认值:

wire [7:0] wb_rd_data = 0;

所以应该是

wire [7:0] wb_rd_data;

因此,它对同一条导线有多个分配-从端口和默认值开始分配,冲突的位表示为Xs。

我必须尝试在Diamond中对此进行综合以发现问题。

2 (Verilog)测试台等待

我在为加法器创建测试平台时遇到问题。 当我启动测试平台时,它将把初始开始时间指定为t1并输入a和b而当cout是1时,它将把最终时间设置为t2 。 最后,延迟是将t2和t1相减。 问题主要是语法错误。 到目前为止,这是我的代码: 感谢您的帮助。 ...

3 Verilog测试台比较

我有五个电路仿真的结果和一些测试,结果将在故障表中注明。 现在,我必须将新电路生成的值与上述电路仿真中已有的值进行比较。 我这样做是为了知道我的新电路是哪个故障类。 如何将以前模拟的值存储在测试平台中,如何将新值与先前存储的结果在同一测试平台中进行比较,以及它匹配的故障类我必须打印 ...

4 verilog测试台比较原因错误

我有一个最特殊的问题,就是我办公室里的所有人都没有遇到过或不知道如何处理,也许你们会发现问题所在。 在我的verilog测试平台中,我具有以下比较代码: ...(直到5个字节) else $display("Success!"); 现在的问题是,2的比较总是失败,而其余的比 ...

2013-10-10 08:59:55 2 243   verilog
6 Verilog测试台状态图

我有一个家庭作业问题,需要为一台粉状机制作状态图,每当连续输入3个或更多1时,该状态机就会输出一个。 我想出了它,并且在我的case(状态)中概述了它的查看方式,我觉得它是正确的,因为它可以很好地编译。 我认为我的问题是我的测试台。 这一切都在一个文件中,但为了使我的解释更容易而分解了…… ...

2015-12-09 23:35:24 1 391   verilog
8 我可以从系统Verilog测试台通过DPI调用获得C例程的调用图吗?

我正在做一个验证项目。 某些测试平台组件是用c编写的,可通过DPI调用,c例程很广泛,而且我很难确定谁调用了哪个例程。 一个纯C程序可能是我可以将cachegrind用于此任务。 在这种情况下,不是main()在进行调用,而是在事件上触发。 有什么方法可以让我了解模拟过程中执行的呼叫顺序 ...

9 Verilog中的浮点加法器测试台

我想写浮点双精度加法器 。 在测试台上,我遇到了一些问题。 * adder是一个模块,它获取两个64位数字并给出它们的总和。 这是我的测试台: 当我加( $bitstoreal(fa)/(2**52) )与一个,fa2得到1! 但是当我不添加它时, fa2实际值为(f ...

2015-04-01 07:45:32 1 1800   verilog
10 使用 Verilog 的 Mux 4x1 测试台

我正在尝试使用测试平台来测试 4X1 多路复用器的某些功能 [a,b,c,d 是输入,z 是输出,s 是选择线]。 这是我的代码: 这是波形: 内核显示测试 1 已通过,即 z=0: 但是,正如您从 15ns 时刻的波形中看到的(仿真时间尺度为 1ns/1ns),z=1。 为什么执行i ...

2020-05-03 16:18:01 1 1400   verilog
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM