verilog中定义 enum 状态机

在这里插入图片描述
fsm

  // fsm states
   //                                       000    001     010       011      100        101
   typedef enum 			   logic [2:0] {IDLE, AWVALID, WRDY, INCR_ENTRY, INCR_Q, CHK_VLD_Q} states_t;
   states_t curr_st, next_st;

   //==========================================================================
   // wires and registers declarations
   //==========================================================================
   logic [14:0] 				   entry_num;
   logic [5:0] 					   queue_num;
   logic [15:0] 				   queue_num_wrdata;
   logic [15:0] 				   entry_num_wrdata;

   /***************************************************************************
    *
    * 
    * AXI write generates one entry by one entry to CQ with correct data
    * 
    * 
    **************************************************************************/
   assign s_axi_ssd_awid    = 'h0;
   assign s_axi_ssd_awlen   = 'h0;
   assign s_axi_ssd_awburst = 2'b01;
   assign s_axi_ssd_awsize  = 3'b100;  //128bits
   assign s_axi_ssd_awcache = 4'h0;
   assign s_axi_ssd_awprot  = 3'b000;
   assign s_axi_ssd_wstrb   = '1;
   assign s_axi_ssd_wlast   = 1'b1; // as there's only 1 beat per write
   assign s_axi_ssd_bready  = 1'b1;
   assign queue_num_wrdata  = queue_num + 1'b1;
   assign entry_num_wrdata  = entry_num + 1'b1;

   // 
   always_ff @ (posedge clk_core)
     begin //{
	if (!rst_n_core)
	  begin //{
	     curr_st <= IDLE;
	  end //}
	else
	  begin //{
	     curr_st <= next_st;
	  end //}
     end //}

   always_comb
     begin //{
	case (curr_st) //{
	  IDLE:
	    begin //{
	       next_st = current_ssd_sq_chk_done ? AWVALID : curr_st;
	    end //}
	  AWVALID:
	    begin //{
	       next_st = s_axi_ssd_awready ? WRDY : curr_st;
	    end //}
	  WRDY:
	    begin //{
	       if (s_axi_ssd_wready)
		 begin //{
		    // if last entry for that queue has been written:
		    if (sq_rxed[ssd_count_in][queue_num] - 1'b1 == entry_num)
		      begin //{
			 // if CQs for all queues are done writing go back to IDLE
			 if (queue_num == NUM_SQS - 1)
			   begin //{
			      next_st = IDLE;
			   end //}
			 // if not all CQs are written increment queue number
			 else
			   begin //{
			      next_st = INCR_Q;
			   end //}
		      end //}
		    // if all CQs for that queue are not written yet, write further
		    // CQs
		    else
		      begin //{
			 next_st = INCR_ENTRY;
		      end //}
		 end //}
	       else
		 begin //{
		    next_st = curr_st;
		 end //}
	    end //}
	  // increment entry number and generate AWVALID
	  INCR_ENTRY:
	    begin //{
	       next_st = AWVALID;
	    end //}
	  // increment Q and check for its validity
	  INCR_Q:
	    begin //{
	       next_st = CHK_VLD_Q;
	    end //}
	  default: // CHK_VLD_Q
	    begin //{
	       // if the incremented queue doesn't have any valid data
	       if (sq_rxed[ssd_count_in][queue_num] == 'h0)
		 begin //{
		    // and if this is the last queue go back to IDLE
		    if (queue_num == NUM_SQS - 1)
		      begin //{
			 next_st = IDLE;
		      end //}
		    // or else increment the queue to check for validity
		    // of next queue
		    else
		      begin //{
			 next_st = INCR_Q;
		      end //}
		 end //}
	       // if the incremented queue has valid data, go back to AWVALID
	       else
		 begin //{
		    next_st = AWVALID;
		 end //}
	    end //}
	endcase //}
     end //}

   // when all CQs are written fsm goes to IDLE and that's when CQ write done is set
   assign cq_write_done = (curr_st != IDLE) & (next_st == IDLE);

   // AWValid generation
   always_ff @ (posedge clk_core)
     begin //{
	if (!rst_n_core)
	  begin //{
	     s_axi_ssd_awvalid <= 1'b0;
	     s_axi_ssd_awaddr  <= 'h0;
	  end //}
	else if (next_st == AWVALID)
	  begin //{
	     s_axi_ssd_awvalid <= 1'b1;
	     s_axi_ssd_awaddr  <= CQ_ADDR_ARRAY[ssd_count_in][queue_num] + (entry_num << 4);
	  end //}
	else
	  begin //{
	     s_axi_ssd_awvalid <= 1'b0;
	  end //}
     end //}

   // wvalid and wdata
   always_ff @ (posedge clk_core)
     begin //{
	if (!rst_n_core)
	  begin //{
	     s_axi_ssd_wvalid <= 1'b0;
	     s_axi_ssd_wdata  <= 'h0;
	  end //}
	else if (next_st == WRDY)
	  begin //{
	     s_axi_ssd_wvalid <= 1'b1;
		                      //       p                                              sq header pointer
	     s_axi_ssd_wdata  <= {15'd0,1'b1,8'd0,entry_num,10'd0, queue_num_wrdata, entry_num_wrdata,64'd0};
	  end //}
	else
	  begin //{
	     s_axi_ssd_wvalid <= 1'b0;
	  end //}
     end //}

   // entry number increment
   always_ff @ (posedge clk_core)
     begin //{
	if (!rst_n_core)
	  begin //{
	     entry_num <= 'h0;
	  end //}
	else if (next_st == INCR_ENTRY)
	  begin //{
	     entry_num <= entry_num + 1'b1;
	  end //}
	else if ((next_st == INCR_Q) | ((curr_st == WRDY) & (next_st == IDLE)))
	  begin //{
	     entry_num <= 'h0;
	  end //}
     end //}

   always_ff @ (posedge clk_core)
     begin //{
	if (!rst_n_core)
	  begin //{
	     queue_num <= 'h0;
	  end //}
	else if (next_st == INCR_Q)
	  begin //{
	     queue_num <= queue_num + 1'b1;
	  end //}
	else if (next_st == IDLE)
	  begin //{
	     queue_num <= 'h0;
	  end //}
     end //}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值