微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > Verilog写的简单数据统计模块,仿真却总是出错

Verilog写的简单数据统计模块,仿真却总是出错

时间:10-02 整理:3721RD 点击:
写了一个简单的数据统计模块,采用内部ip生成的 single port RAM,
Read状态读入原值,Write状态加1后存入原地址,够10个后输出统计值。
但是仿真结果输出为0,addr为红色未知状态,请高手看看是什么原因。
verilog代码如下。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
module histo_count(
   clk,
    wea,
    rst_n,
    Result
    );
parameter WIDTH = 8;
parameter DEPTH_BITS = 8;
input  clk;
input  wea;
input  rst_n;
output [7:0]Result;
// output register
reg  [WIDTH-1:0]         addr;
wire [DEPTH_BITS-1:0]    d_out;
reg  [DEPTH_BITS-1:0]    d_in;
reg all_output = 0;
//INSTANTIATION
si_ram s_ram_1(
  .clka(clk),   // input clka
  .wea(wea),    // input [0 : 0] wea
  .addra(addr), // input [7 : 0] addra
  .dina(d_in),  // input [7 : 0] dina
  .douta(d_out) // output [7 : 0] douta
);
         
//FSM
parameter [4:0]                // single hot
  IDLE =             5'b00001,
  Read =             5'b00010,
  Write =            5'b00100,
  Read_all   =    5'b01000,
  Save_all   =    5'b10000;
  
reg [4:0]current_state;
reg [4:0]next_state;
reg [7:0] i = 8'b0; // counter
reg [7:0] k = 8'b0; // counter


always @ (posedge clk or negedge rst_n)   
if(!rst_n)
   current_state <= IDLE;
else
   current_state <= next_state;

always @ (*)  //to supress warning, use * in the sensative list.
  begin
   
    case(current_state)                                 
         
     IDLE:   begin
                  if(!rst_n)
                          next_state = IDLE;
                      else
                      next_state = Read;
                end
     
     Read:   begin
                   if (i==10)begin
                        all_output = 1;
                        next_state = Read_all;
                                  end
                        
                        else          begin
                        addr <= d_in;           
                    next_state = Write;  
                                end                        
              end
               
     Write:  begin                        
                        if(wea) // do i need this if?
                         d_in <= d_out + 1;
                        i = i + 1;
                    next_state = Read;
                end
   
     Read_all: begin  
                      if(k==10) begin
                          k = 0;
                            next_state = IDLE;
                                  end
                                    
                      else     begin
                         addr <= k;
                          k = k + 1;
                          next_state = Read_all;
                                 end
                  end
                  
     default:  next_state = IDLE;
    endcase
end
assign  Result = (all_output)? d_out : 0;
endmodule

状态机里always @ (*)  ,为啥用这个



   这个是新写法,相当于把所有的敏感列表都放进去。

TB代码呢?

仿真时,把current_state、next_state、i、k、all_output、addr、din等变量都添加到仿真波形中,你再根据current_state、next_state、i、k来分析FSM代码,查看是否逻辑上是否有问题!你会发现问题的!

你都已经发现addr是红线了,继续往前推理就是了。addr《=d_in,显然是由d_in决定的,而d_in在上电的时候没有确定值,当然不行了。
写代码的时候,reg最好都赋初值,或者rst的时候赋值

没有复位

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top