///利用位宽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