module USB_command(
input clk ,
input pclk_in ,
input rst_n ,
//usb
input flag_a ,
input flag_b ,
input flag_c ,
input flag_d ,
output wirepclk ,
output wireslcs ,
output reg sloe ,
output regslrd ,
output regslwr ,
output wirepktend ,
output reg [ 1: 0] fifo_addr ,
inoutwire [31: 0] usb_data ,
output regcmd_flag ,
output wire [31: 0] cmd_data
);
parameter IDLE = 4'b0001 ;
parameter WRITE = 4'b0010 ;
parameter READ = 4'b0100 ;
reg [ 3: 0] state_c /*synthesis preserve*/ ;
reg [ 3: 0] state_n /*synthesis preserve*/ ;
//cnt
reg [31: 0] cnt ;
wire add_cnt ;
wire end_cnt ;
reg [15: 0] rd_cnt ;
reg [15: 0] rd_data_len ;
regwr_trig ;//写触发
assign slcs = 1'b0;
assign pclk = pclk_in;
assign pktend = 1'b1;
assign usb_data = (!slwr) ? usb_write_data : 32'dz;
wire[31:0] usb_write_data ;
//state_c
always@(posedgeclk or negedgerst_n)begin
if(!rst_n)begin
state_c<= IDLE;
end
else begin
state_c<= state_n;
end
end
//state_n
always@(*)begin
case(state_c)
IDLE:begin
if(flag_a&&flag_b&&wr_trig)begin
state_n = WRITE;
end
else if(flag_c&&flag_d)begin
state_n = READ;
end
else begin
state_n = state_c;
end
end
WRITE:begin
if(flag_b == 1'b0)begin //写满
state_n = IDLE;
end
else begin
state_n = state_c;
end
end
READ:begin
if(flag_d == 1'b0)begin //读空
state_n = IDLE;
end
else begin
state_n = state_c;
end
end
default:begin
state_n = IDLE;
end
endcase
end
//fifo_addr
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
fifo_addr<= 2'b00;
sloe <= 1'b1;
end
else if(state_c==READ)begin
fifo_addr<= 2'b11;
sloe <= 1'b0;
end
else begin
fifo_addr<= 2'b00;
sloe <= 1'b1;
end
end
//slwr 输出信号,用时序逻辑好点
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
slwr<= 1'b1;
end
else if(state_c==WRITE)begin
slwr<= 1'b0;
end
else begin
slwr<= 1'b1;
end
end
//slrd
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
slrd<= 1'b1;
end
else if(state_c==READ)begin
slrd<= 1'b0;
end
else begin
slrd<= 1'b1;
end
end
//rd_cnt
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
rd_cnt<= 16'd0;
end
else if(slrd)begin
rd_cnt<= 16'd0;
end
else begin
rd_cnt<= rd_cnt + 1'b1;
end
end
//rd_data_len
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
rd_data_len<= 16'd0;
end
else if(rd_cnt == 16'd3)begin
rd_data_len<= usb_data + 16'd3;
end
end
//cmd_flag
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
cmd_flag<= 1'b0;
end
else if(rd_cnt == 16'd3)begin
cmd_flag<= 1'b1;
end
else if(rd_cnt == rd_data_len)begin
cmd_flag<= 1'b0;
end
end
assign cmd_data = usb_data ; //将cmd_flag与cmd_data配合使用
//cnt
always @(posedgeclk or negedgerst_n)begin
if(!rst_n)begin
cnt<= 0;
end
else if(add_cnt)begin
if(end_cnt)
cnt<= 0;
else
cnt<= cnt + 1;
end
else begin
cnt<= 0;
end
end
assign add_cnt = state_c==WRITE;
assign end_cnt = add_cnt&&cnt == 4096-1; //测试用的计数数据
//wr_trig
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
wr_trig<= 1'b0;
end
else if(cmd_flag&&cmd_data == 32'h11111111)begin
wr_trig<= 1'b1;
end
//else if(slwr == 1'b0)begin //开始写的时候,将wr_trig拉低
// wr_trig<= 1'b0;
//end
end
//fifo 读请求
regfifo_rdeq;
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
fifo_rdeq<= 1'b0;
end
else if(flag_a )begin
fifo_rdeq<= 1'b1;
end
else fifo_rdeq<= 1'b1;
end
//fifo 写请求
regfifo_wdeq;
always @(posedgeclk or negedgerst_n)begin
if(rst_n == 1'b0)begin
fifo_wdeq<= 1'b0;
end
else if(flag_c)begin
fifo_wdeq<= 1'b1;
end
else fifo_wdeq<= 1'b1;
end
//FIFO
fifo fifo_inst (
.clock (clk),
.data ( cnt ),
.rdreq ( fifo_rdeq ),
.wrreq ( fifo_wdeq ),
.q ( usb_write_data )
);
Endmodule
|