【无标题】双口RAM的读操作

///利用位宽64位,深度为512的双口RAM来进行数据的读取,在数据的读取时,因为涉及到300个地址,而考虑到芯片逻辑的问题,不能一//一列出所有的状态,因而利用五个状态来判断当前应当执行的操作以及要读取的数据

module read(

	input		     clk,
	input		     rst_n,
	input  			  sys_on,
	
	input  	[31:0]  cycle_time,
	
	input           wave300_channel,
	 
	input    [8:0]   cnt_word,
	 
	input   [63:0]  param_data,
	
	output reg ch_cs,
	 
	output   reg [15:0]  ch_data 
 );
 
 
//reg [8:0] cfg_cnt; 
reg [8:0]  rdaddr;
wire [63:0] param_out;

ram u_ram(
 	.data           (param_data),            //[63:0],[63:48]????????????[47:0]????	
	.wraddress      (cnt_word),            //[8:0]
	.wrclock        (clk),            //
	.wren           (sys_on),            //
	
	.rdaddress      (rdaddr),            //[8:0]
	.rdclock        (clk),            //				
		
	.q              (param_out)             //[63:0]
	
);


reg [15:0]   cnt_loop;  
reg [15:0]   cnt_num;
reg [31:0]   cycle_cnt;
reg flag;
reg cfg_valid;
always @(posedge clk or negedge rst_n)begin
       if(!rst_n)
          cfg_valid <= 1'b0;
       else if(rdaddr >= 9'd1  )
          cfg_valid <= 1'b1;
       else
          cfg_valid <= 1'b0;
end

always @(posedge clk or negedge rst_n)begin
       if(!rst_n)
          cycle_cnt <= 32'b0;
		 else if(|cfg_valid)begin
				 if(cycle_cnt >= (cycle_time-1))
					  cycle_cnt <= 32'b0;
				 else 
					  cycle_cnt <= cycle_cnt + 32'd1;
		 end
		 else
		    cycle_cnt <= 32'b0;
end
always @(posedge clk or negedge rst_n)begin
       if(!rst_n)
          flag <= 1'b0;
       else if(cycle_cnt >= (cycle_time-1))
          flag <= 1'b1;
       else 
          flag <= 1'b0;
end

reg [15:0] reg_addr;  循环地址,是要循环的地址中列出的地址,从此开始循环
reg [15:0] reg_rdaddr; /要循环的地址
reg [15:0] reg_addr_cnt;///要循环的地址要循环的次数

											
parameter IDLE = 3'd0;
parameter WR_DATA1 = 3'd1;
parameter WR_DATA2 = 3'd2;
parameter WR_DATA3 = 3'd3;
parameter WR_DATA4 = 3'd4;


//wire [8:0]  IDLE;
reg  [2:0]  Current_state;
reg  [2:0]  Next_state;

 // FSM 1
always @ (posedge clk or negedge rst_n)begin   
	if(!rst_n)
		Current_state <= IDLE;
	else
		Current_state <= Next_state;
end   
	
// FSM 2
always @(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
		Next_state <= IDLE;
		ch_data <= 16'd0;
	   reg_addr <= 16'd0;	
		rdaddr <= 9'd0;
		cnt_num <= 16'd0;
		cnt_loop <= 16'b0;
		reg_rdaddr <= 16'b0;
		reg_addr_cnt <= 16'b0;
	end
	else if(wave300_channel)begin
			case(Current_state)
			  IDLE:begin
				  if(sys_on)begin
					    Next_state <= WR_DATA1;
						 rdaddr <= 9'd0;
						 ch_data <= 16'd0;
						 reg_addr <= 16'd0;
				  end
				  else begin
					    Next_state <= IDLE;
						 rdaddr <= 9'd0;
						 ch_data <= 16'd0;
						 reg_addr <= 16'd0;
				  end  
			  end
           WR_DATA1:begin
					  if(sys_on)begin
								if(cnt_word > 9'd6)begin
									 rdaddr <= 9'd1;
									 Next_state <= WR_DATA2;
									 ch_data <= 16'd0;
									 reg_addr <= 16'd0;
							   end
							   else begin
								    Next_state <= WR_DATA1;
									 ch_data <= 16'd0;
									 reg_addr <= 16'd0;
									 rdaddr <= 9'd0;
							   end	
					  end
					  else begin
					            Next_state <= IDLE;
									ch_data <= 16'd0;
									reg_addr <= 16'd0;
									rdaddr <= 9'd0;
					  end
			  end
			  WR_DATA2:begin判断重复次数有没有
					  if(sys_on)begin
                        if(param_out[47:32] > 16'b0)begin/?????
									ch_data <= param_out[63:48];       								      
										if(cnt_num >= param_out[47:32])begin
											 Next_state <= WR_DATA3;
											 rdaddr <= rdaddr;
											 reg_addr <= reg_addr;
											 reg_addr_cnt <= reg_addr_cnt;
											 reg_rdaddr <= reg_rdaddr;
											 cnt_num <= 16'd0;
											 cnt_loop <= cnt_loop;
										end
										else begin
										    Next_state <= WR_DATA2;
											 rdaddr <= rdaddr;
											 reg_addr <= reg_addr;
											 reg_addr_cnt <= reg_addr_cnt;
											 reg_rdaddr <= reg_rdaddr;
											 cnt_loop <= cnt_loop;
											 if(flag)
											     cnt_num <= cnt_num + 16'b1;
											 else
											     cnt_num <= cnt_num; 
												   
										end
								end
						      else begin
								    ch_data <= 16'd0;       
						          rdaddr <= rdaddr + 9'b1;
									 Next_state <= WR_DATA2;
									 reg_addr <= reg_addr;
									 reg_addr_cnt <= reg_addr_cnt;
									 reg_rdaddr <= reg_rdaddr;
									 cnt_loop <= cnt_loop;
				            end		
					  end
					  else begin
					            ch_data <= 16'd0;
                           rdaddr <= 9'd0;
									Next_state <= IDLE;
									reg_addr <= 16'd0;
									cnt_loop <= 16'd0;
					  end
			  end
			  WR_DATA3:begin/判断循环地址有没有
					  if(sys_on)begin
                        if(param_out[15:0] > 16'd0)begin/循环地址
								      if(reg_addr_cnt)begin//循环次数
											   ch_data <= ch_data;       ??								
												if(rdaddr == reg_rdaddr)begin
												     if(cnt_loop == reg_addr_cnt - 1'b1)begin
												            cnt_loop <= cnt_loop;
																Next_state <= WR_DATA4;
													  end
													  else begin
													         cnt_loop <= cnt_loop + 16'b1;
													         rdaddr <= reg_addr;
																Next_state <= WR_DATA2;
													  end
												end
												else begin
												     cnt_loop <= cnt_loop;
													  rdaddr <= rdaddr + 9'd1;
													  Next_state <= WR_DATA2;
												end
										end
										else begin
										      ch_data <= ch_data;       ??								
											   Next_state <= WR_DATA4;
												reg_addr_cnt <= 16'd0;
											   rdaddr <= rdaddr;
												cnt_loop <= cnt_loop;
										end
								end
						      else begin
									 ch_data <= ch_data;       ??
									 if(reg_addr_cnt)begin
									    if(rdaddr == reg_rdaddr)begin
												 if(cnt_loop == reg_addr_cnt - 1'b1)begin
														cnt_loop <= cnt_loop;
														Next_state <= WR_DATA4;
												 end
												 else begin
														cnt_loop <= cnt_loop + 16'b1;
														rdaddr <= reg_addr;
														Next_state <= WR_DATA2;
												 end
										  end
										  else begin
										           cnt_loop <= cnt_loop;
													  rdaddr <= rdaddr + 9'd1;
													  Next_state <= WR_DATA2;
										  end
									 end
									 else begin
									    Next_state <= WR_DATA2;
									    cnt_loop <= cnt_loop;
										 rdaddr <= rdaddr + 9'd1;
									 end
				            end		
					  end
					  else begin
                           rdaddr <= 9'd0;
									Next_state <= IDLE;
									reg_addr <= 16'd0;
									ch_data <= 16'd0;       ??
									cnt_loop <= 16'd0;
					  end
			  end
			  WR_DATA4:begin/判断循环次数有没有完成
					  if(sys_on)begin
					       ch_data <= ch_data;       ??
								if(cnt_loop >= param_out[31:16]  - 1'b1)begin	循环次数										
									 rdaddr <= rdaddr + 9'b1;
									 Next_state <= WR_DATA2;
									 reg_addr_cnt <= 16'd0;
									 cnt_loop <= 16'd0;
									 reg_rdaddr <= 16'd0;
									 reg_addr <= 16'd0;
								end
								else begin
									 Next_state <= WR_DATA2;
									 reg_rdaddr <= rdaddr;
									 rdaddr <= param_out[8:0];
									 reg_addr <= param_out[8:0];
									 reg_addr_cnt <= param_out[31:16];
									 cnt_loop <= 16'b1;
								end		
					  end
					  else begin
                           rdaddr <= 9'd0;
									reg_addr <= 16'd0;
									ch_data <= 16'd0;       ??
									Next_state <= IDLE;
					  end
			  end
			  
			  default :begin   rdaddr <= 9'd0;
			                   reg_addr <= 16'd0;
			                   ch_data <= 16'd0;       ??
			                   Next_state <= IDLE;
						  end
			  endcase
   end
	else begin
	   	Next_state <= 3'd0;
			rdaddr <= 9'd0;
		   ch_data <= 16'd0;
	end
end



  
always @(posedge clk or negedge rst_n )begin
		if(!rst_n)
			ch_cs <= 1'b1;
		else if((Next_state == IDLE)	||  (Next_state == WR_DATA1)	||  (Next_state == WR_DATA2)	||  (Next_state == WR_DATA3) 	|| (Next_state == WR_DATA4) )
			ch_cs <= 1'b0;
		else 
			ch_cs <= 1'b1;
end
	
endmodule 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值