2014-04-23 3 views
1

며칠 전 입력 샘플의 MSB를 취하여 누적하고 (누적하여) 출력 샘플에 결합하는 모듈을 구현하려고했습니다 (here). 32 출력 비트가 "채워짐"상태입니다.내 MSB 다운 샘플링 모듈에 대한 Verilog 테스트 벤치 디자인

module my_rx_dsp0 
#(
    //frontend bus width 
    parameter WIDTH = 24 
) 
(
    //control signals 
    input clock, //dsp clock 
    input reset, //active high synchronous reset 
    input clear, //active high on packet control init 
    input enable, //active high when streaming enabled 

    //user settings bus, controlled through user setting regs API 
    input set_stb, input [7:0] set_addr, input [31:0] set_data, 

    //full rate inputs directly from the RX frontend 
    input [WIDTH-1:0] frontend_i, 
    input [WIDTH-1:0] frontend_q, 

    //full rate outputs directly to the DDC chain 
    output [WIDTH-1:0] ddc_in_i, 
    output [WIDTH-1:0] ddc_in_q, 

    //strobed samples {I16,Q16} from the RX DDC chain 
    input [31:0] ddc_out_sample, 
    input ddc_out_strobe, //high on valid sample 
    output ddc_out_enable, //enables DDC module 

    //strobbed baseband samples {I16,Q16} from this module 
    output reg [31:0] bb_sample, 
    output reg bb_strobe //high on valid sample 
); 

    reg [3:0] i_msb; 
    reg [3:0] q_msb; 

    reg [31:0] temp_buff = 0; 
    reg [1:0] count = 0; 

    always @(posedge clock) begin 
     if(ddc_out_strobe) begin 
      // bit shifter for MSB 
      temp_buff <= {i_msb,q_msb,temp_buff[31:8]}; 
      // to avoid if-else condition 
      count <= (count==2'd3) ? 2'd0 : (count+1); 
     end 
    end 

    always @(*) begin 
     i_msb = ddc_out_sample[31:28]; 
     q_msb = ddc_out_sample[15:12]; 
     // to avoid if-else condition 
     bb_strobe = (count==2'd3); 
     bb_sample = bb_strobe ? temp_buff : 32'd0; 
    end 

    assign ddc_in_i = frontend_i; 
    assign ddc_in_q = frontend_q; 
    assign ddc_out_enable = enable; 

endmodule //my_rx_dsp0_custom 

지금은 몇 가지 예와 my_rx_dsp0.v을 테스트하는 테스트 벤치를 구현하고 싶었 : 거기에 도움을

덕분에, 나는 어떤 컴파일 오류를 생성하지 않습니다이 구현을 가지고 자일링스 12.1 좋은 듯 . 나는 my_input.dat이라는 파일에서 32 비트 샘플을 읽어 으로 모듈에 공급하는 my_rx_dsp0_tb_2.v을 구현했습니다. 그런 다음 my_output.dat에 저장된 올바른 값과 비교됩니다.

참고 : 나는이 테스트 벤치를 직접 작성하지 않았고 오픈 소스 프로젝트의 다른 테스트 벤치에서 수정했습니다.

module my_rx_dsp0_tb (); 

reg clk; 
reg reset; 
reg enable; 
reg ddc_out_strobe; //high on valid sample 
reg [31:0] ddc_out_sample; 
wire [31:0] bb_sample = 32'd0; 
wire bb_strobe; 
wire ddc_out_enable = 1'b1; //enables DDC module 

parameter WIDTH = 24; 
parameter clocks = 2; // number of clocks per input 

reg endofsim = 0; 
integer number_of_errors; 
initial number_of_errors = 0; 

wire set_stb = 1; 
wire [7:0] set_addr; 
wire [31:0] set_data; 
wire [WIDTH-1:0] frontend_i; 
wire [WIDTH-1:0] frontend_q; 
wire [WIDTH-1:0] ddc_in_i; 
wire [WIDTH-1:0] ddc_in_q; 

reg signed [31:0] compare_out; 

// Setup the clock 
initial clk = 1'b0; 
always #5 clk <= ~clk ; 

// Come out of reset after a while 
initial reset = 1'b1 ; 
initial #1000 reset = 1'b0 ; 

// Enable the entire system 
initial enable = 1'b1 ; 

// Instantiate UUT 
my_rx_dsp0 #(.WIDTH(WIDTH)) UUT_rx_dsp0 
    ( .clock(clk), .reset(reset), .clear(clear), .enable(enable), 
     .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), 
     .frontend_i(frontend_i), .frontend_q(frontend_q), 
     .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q), 
     .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), .ddc_out_enable(ddc_out_enable), 
     .bb_sample(bb_sample), .bb_strobe(bb_strobe)); 

//-------Setup file IO-------// 
// 
integer i, r_in, r_out, infile, outfile; 

initial begin 
    infile = $fopen("my_input.dat","r"); 
    outfile = $fopen("my_output.dat","r"); 
    $timeformat(-9, 2, " ns", 10) ; 
    // for n=9,p=2 digits after decimal pointer 
    //min_field_width=10 number of character positions for %t 
end  

//-------Get sim values and display errors-------// 
// 
initial begin 
    // Initialize inputs 
    ddc_out_strobe <= 1'd0; 
    ddc_out_sample <= 32'd0; 

    // Wait for reset to go away 
    @(negedge reset) #0; 

    while(!endofsim) begin 
     // Write the input from the file or 0 if EndOfFile(EOF) 
     @(posedge clk) begin 
      #1 
      ddc_out_strobe <= 1'b1; 
      if(!$feof(infile)) 
       r_in = $fscanf(infile,"%b\n",ddc_out_sample); 
      else 
       ddc_out_sample <= 32'd0; 
     end 
     // 
     // Clocked in; set the strobe to 0 if the # of clocks/sample 
     // is greater than 1 
     if(clocks > 1) begin 
      @(posedge clk) begin 
       ddc_out_strobe <= 1'b0 ; 
      end 

      // Wait for the specified # of cycles 
      for(i = 0 ; i < (clocks-2) ; i = i + 1) begin 
       @(posedge clk) #1 ; 
      end 
     end 
     // 

     // 
     // Print out the number of errors that occured 
     if(number_of_errors) begin 
      $display("FAILED: %d errors during simulation",number_of_errors) ; 
     end else begin 
      $display("PASSED: Simulation successful") ; 
     end 
     // 
    end 
end 

//-------Comparison btwn simulated values vs known good values-------// 
// 
always @(posedge clk) begin 
    if(reset) 
     endofsim <= 1'b0 ; 
    else begin 
     if(!$feof(outfile)) begin 
      if(bb_strobe) begin 
       r_out = $fscanf(outfile,"%b\n",compare_out); 
       if(compare_out != bb_sample) begin 
        $display("%t: %b != %b",$realtime,bb_sample,compare_out); 
        number_of_errors = number_of_errors + 1; 
       end else begin 
        $display("%t: %b = %b",$realtime,bb_sample,compare_out); 
       end 
      end 
     end else begin 
      // Signal end of simulation when no more outputs 
      endofsim <= 1'b1 ; 
     end 
    end 
end 

endmodule // my_rx_dsp0_tb 

것은 내가 모듈에서 원하는 기능을하지 않는 자일링스 ISE 스위트 에디션 12.1에서 ISIM으로 시뮬레이션 : 여기

의 구현입니다. 출력에 1 또는 0을 예상대로 여러 x 상태 (알 수없는 상태)가 포함되어 있습니다. 파일이 $fscanf 읽을되고있다

1) 방법 :

질문이 인해인가?

2) reg [31:0] temp_buff = 0 초기화를 잘못 했습니까?

3) 또는 누군가가 무엇이 잘못되었는지 아이디어가 있습니까?

오류는 테스트 벤치에서 프롬프트 (예를 들어)과 같습니다 X는 bb_sampleddc_out_enable 여러 충돌 드라이버를 구비 내지 xx000x00xxx00x0xx000x0x000000000 != 10000110111001011100010001101100

답변

0

. wire 형식은 드라이버를 병합합니다. 동일한 강도의 충돌하는 비트 값은 X로 해결됩니다.

UUT_rx_dsp0은 의도 한 다이버입니다. 그러나 당신은 당신이 당신의 전선을 선언 한 길에서 추가 된 드라이버를 추가했습니다.

... 
wire [31:0] bb_sample = 32'd0; // "= 32'd0" is a continuous driver 
wire bb_strobe; 
wire ddc_out_enable = 1'b1; // "= 1'd1" is a continuous driver 
...

당신이 원하는 것은 다음 X의 문제를 해결할 수 위의 수정

... 
wire [31:0] bb_sample; 
wire bb_strobe; 
wire ddc_out_enable; 
...

. 예제 오류를 기반으로 그것은 데이터 누락과 일치하는 것처럼 보입니다. 제공된 정보로 테스트 벤치 또는 디자인 문제인지 여부를 판단하기가 어렵습니다. 그냥 시계 또는 전파 왜곡 일 수 있습니다.

+0

감사합니다. @Greg,'x'의 문제가 수정되었습니다 :) 이제 값이 여전히 일치하지 않기 때문에 아마 모듈을 수정해야 할 것입니다. 테스트 벤치 또는 디자인 문제인지 알려면 추가 정보가 필요합니까?또는 그 시계 또는 전파 왜곡? –

+0

파형 덤핑은 디버깅에 도움이됩니다. '$ dumpfile ("dump.vcd"); $ dumpvars;'. 이를 설계 요구 사항과 비교하십시오. 데이터가 빠르거나 느린 사이클이면 오프셋 문제입니다. 데이터가 완전히 없으면 설계상의 문제입니다. 둘 다있을 수 있습니다. – Greg