📄 usb1_pl.v
字号:
wire rx_busy;
wire tx_busy;
///////////////////////////////////////////////////////////////////
//
// Misc Logic
//
assign x_busy = tx_busy | rx_busy;//不管是发送还是接收,只要忙就是忙
// PIDs we should never receive,主机也可能发送ack的呀??
assign pid_bad = pid_ACK | pid_NACK | pid_STALL | pid_NYET | pid_PRE |
pid_ERR | pid_SPLIT | pid_PING;
assign match_o = !pid_bad & token_valid & !crc5_err;//收到能处理的包标识符,且收到的确实是令牌包或是握手包,且无错
//因为match_o的含义并不很直观,所以才会记不住
// Receiving Setup
always @(posedge clk)
ctrl_setup <= #1 token_valid & pid_SETUP & (ep_sel==4'h0);//只能给端点0,此信号果然是在pl本地产生
always @(posedge clk)
ctrl_in <= #1 token_valid & pid_IN & (ep_sel==4'h0);//控制输入,即要从0端点输入
always @(posedge clk)
ctrl_out <= #1 token_valid & pid_OUT & (ep_sel==4'h0);//控制输出
// Frame Number (from SOF token)
assign frame_no_we = token_valid & !crc5_err & pid_SOF;//帧号写使能信号的产生
always @(posedge clk)
frame_no_we_r <= #1 frame_no_we;//寄存起来
always @(posedge clk or negedge rst)//给frame_no_r赋值
if(!rst) frame_no_r <= #1 11'h0;
else
if(frame_no_we_r) frame_no_r <= #1 frame_no;
//SOF delay counter
always @(posedge clk)
clr_sof_time <= #1 frame_no_we;//允许更新frame_no的同时允许清零sof_time,Time since last sof,很自然
always @(posedge clk)//对sof_time赋值
if(clr_sof_time) sof_time <= #1 12'h0;
else
if(hms_clk) sof_time <= #1 sof_time + 12'h1;//每隔0.5微秒计一次数
assign frm_nat = {4'h0, 1'b0, frame_no_r, 4'h0, sof_time};//一共32位
// 0.5 Micro Seconds Clock Generator 0.5微秒时钟发生器
always @(posedge clk or negedge rst)
if(!rst) hms_cnt <= #1 5'h0;
else
if(hms_clk | frame_no_we_r) hms_cnt <= #1 5'h0;//帧号更新时0.5微妙时钟也要停止
else hms_cnt <= #1 hms_cnt + 5'h1;
always @(posedge clk)//hms_clk为hms_cnt计数的结果所产生的时钟信号
hms_clk <= #1 (hms_cnt == `USBF_HMS_DEL);
always @(posedge clk)
rx_data_st <= rx_data_st_d;//注意,rx_data_st_d是wire型的!!!!看看这里的rx_data_st指什么!!
//rx_data_st是pl内部的一个八位reg,其实是输出寄存器。
///////////////////////////////////////////////////////////////////
// This function is addressed
assign fsel = (token_fadr == fa);//拿输入跟既存内容作比较,fa是先前存的主机分配的设备地址?
// Only write when we are addressed !!!
assign idma_we = idma_we_d & fsel; // moved full check to idma ... & !ep_full;
///////////////////////////////////////////////////////////////////
//
// Module Instantiations
//
//Packet Decoder
usb1_pd u0( .clk( clk ),//外壳引脚
.rst( rst ), //外壳引脚
.rx_data( rx_data ),//外壳引脚
.rx_valid( rx_valid ),//外壳引脚
.rx_active( rx_active ),//外壳引脚
.rx_err( rx_err ),//外壳引脚
.pid_OUT( pid_OUT ),//与协议引擎相接,这里pl内部各模块的相连都要通过wire型变量,即信号线
.pid_IN( pid_IN ),//与协议引擎相接
.pid_SOF( pid_SOF ),//与协议引擎相接
.pid_SETUP( pid_SETUP ),//与协议引擎相接
.pid_DATA0( pid_DATA0 ),//与协议引擎相接
.pid_DATA1( pid_DATA1 ),//与协议引擎相接
.pid_DATA2( pid_DATA2 ),//与协议引擎相接
.pid_MDATA( pid_MDATA ),//与协议引擎相接
.pid_ACK( pid_ACK ),//与协议引擎相接
.pid_NACK( pid_NACK ),//与协议引擎相接
.pid_STALL( pid_STALL ),//与协议引擎相接
.pid_NYET( pid_NYET ),//与协议引擎相接
.pid_PRE( pid_PRE ),//与协议引擎相接
.pid_ERR( pid_ERR ),//与协议引擎相接
.pid_SPLIT( pid_SPLIT ),//与协议引擎相接
.pid_PING( pid_PING ),//与协议引擎相接
.pid_cks_err( pid_cs_err ),//外壳引脚,是要送出去的
.token_fadr( token_fadr ),//包拆装产生,送到pl内部跟外部输入fa作比较得出fsel
.token_endp( ep_sel ),//外壳引脚,输出给pl外部
.token_valid( token_valid ),//外壳引脚,输出的pl模块外部
.crc5_err( crc5_err ),//外壳引脚,输出给pl外部
.frame_no( frame_no ),//关键是这个信号给谁了?给了pl模块内的frame_no_r寄存器。
.rx_data_st( rx_data_st_d ),//给谁了?给了pl模块内的信号线rx_data_st_d
.rx_data_valid( rx_data_valid ),//与idma相接了,给了pl内的一根信号线rx_data_valid
.rx_data_done( rx_data_done ),//与idma相接了,给了pl内的一根信号线rx_data_done
.crc16_err( crc16_err ),//与协议引擎相接,给了pl内的一根信号线crc16_err
.seq_err( rx_seq_err ),//给谁了?给了pl内的一根信号线rx_seq_err
.rx_busy( rx_busy )//给谁了?给了pl内的一根信号线rx_busy,与tx_busy一同构成x_busy
);
// Packet Assembler
usb1_pa u1( .clk( clk ),//外壳引脚
.rst( rst ),//外壳引脚
.tx_data( tx_data ),//外壳引脚,直接输出pl了
.tx_valid( tx_valid ),//外壳引脚,直接输出pl了
.tx_valid_last( tx_valid_last ),//外壳引脚,直接输出pl了
.tx_ready( tx_ready ),//外壳引脚,从pl外部引入到pa
.tx_first( tx_first ),//外壳引脚,直接输出pl了
.send_token( send_token ),//与协议引擎相接,由pe通过信号线send_token传给pa
.token_pid_sel( token_pid_sel ),//与协议引擎相接,由pe通过信号线token_pid_sel传给pa
.send_data( send_data ),//与idma相接,由idma通过信号线send_data传给pa
.data_pid_sel( data_pid_sel ),//与协议引擎相接,由pe通过信号线data_pid_sel传给pa
.tx_data_st( tx_data_st_o ),//与idma相接,由idma通过信号线tx_data_st_o传给pa
.rd_next( rd_next ),//与idma相接,直接输出通过信号线rd_next传给idma
.ep_empty( ep_empty_int)//来自idma,通过信号线ep_empty_int
);
// Internal DMA / Memory Arbiter Interface
usb1_idma
u2( .clk( clk ),//外壳引脚
.rst( rst ),//外壳引脚
.tx_valid( tx_valid ),//由外壳引脚输入,实际上这个信号产生于pa模块
.rx_data_valid( rx_data_valid ),//来自包拆装模块,由pd通过rx_data_valid信号线输入
.rx_data_done( rx_data_done ),//来自包拆装模块,通过rx_data_done信号线输入
.send_data( send_data ),//给包组装模块,通过信号线send_data
.rd_next( rd_next ),//来自包组装模块,通过信号线rd_next
.tx_data_st_i( tx_data_st ),//这里的tx_data_st是理解成wire型呢,还是pl的外壳引脚呢?
.tx_data_st_o( tx_data_st_o ),//给包组装模块了,通过信号线tx_data_st_o
.ep_sel( ep_sel ),//外壳引脚,输入,其实该信号产生于pd模块
.ep_bf_en( ep_bf_en ),//外壳引脚,输入
.ep_bf_size( ep_bf_size ),//外壳引脚,输入
.dropped_frame(dropped_frame ),//外壳引脚,输出
.misaligned_frame(misaligned_frame),//外壳引脚,输出
.tx_busy( tx_busy ),//本地信号,输出到pl内部与rx_busy共同构成x_busy
.tx_dma_en( tx_dma_en ),//来自协议引擎,通过信号线tx_dma_en
.rx_dma_en( rx_dma_en ),//来自协议引擎,通过信号线rx_dma_en
.idma_done( idma_done ),//给协议引擎,通过信号线idma_done
.size( csr[8:0] ),//外部引脚,外部输入csr[13:0],这里取其低九位给idma模块的size脚
.rx_cnt( rx_size ),//外壳引脚,输出给pl外部
.rx_done( rx_done ),//外壳引脚,输出给pl外部
.mwe( idma_we_d ),//输出给信号线idma_we_d,不知他跟idma_we的关系,idma_we也为wire型
.mre( idma_re ),//外部引脚,前面有idma_re的内部信号线和外部引脚的定义,有点乱
.ep_empty( ep_empty ),//外部引脚,输入pl模块
.ep_empty_int( ep_empty_int ),//给了pl内的信号线ep_empty_int
.ep_full( ep_full )//外部引脚,输入pl模块
);
// Protocol Engine
usb1_pe
u3( .clk( clk ),//外壳引脚
.rst( rst ),//外壳引脚
.tx_valid( tx_valid_out ),//外壳引脚,输入。tx_valid_out出自何处?
.rx_active( rx_active ),//外壳引脚,输入
.pid_OUT( pid_OUT ),//来自包拆装模块,通过信号线pid_OUT
.pid_IN( pid_IN ),//来自包拆装模块
.pid_SOF( pid_SOF ),//来自包拆装模块
.pid_SETUP( pid_SETUP ),//来自包拆装模块
.pid_DATA0( pid_DATA0 ),//来自包拆装模块
.pid_DATA1( pid_DATA1 ),//来自包拆装模块
.pid_DATA2( pid_DATA2 ),//来自包拆装模块
.pid_MDATA( pid_MDATA ),//来自包拆装模块
.pid_ACK( pid_ACK ),//来自包拆装模块
.pid_PING( pid_PING ),//来自包拆装模块
.token_valid( token_valid ),//外壳引脚,实际该信号产生于pd模块
.rx_data_done( rx_data_done ),//来自包拆装模块,通过信号线rx_data_done
.crc16_err( crc16_err ),//来自包拆装模块,通过信号线crc16_err
.send_token( send_token ),//给包组装模块,通过信号线send_token
.token_pid_sel( token_pid_sel ),//给包组装模块,通过信号线token_pid_sel
.data_pid_sel( data_pid_sel ),//给包组装模块,通过信号线data_pid_sel
.rx_dma_en( rx_dma_en ),//给idma模块,通过信号线rx_dma_en
.tx_dma_en( tx_dma_en ),//给idma模块,通过信号线tx_dma_en
.abort( abort ),//给idma模块,通过信号线abort,谁说的???????????///
.idma_done( idma_done ),//来自于idma模块,通过信号线idma_done
.fsel( fsel ),//本地信号,fsel = (token_fadr == fa),输入给pe
.ep_sel( ep_sel ),//外壳引脚,输入pe,实际产生于pd
.ep_full( ep_full ),//外壳引脚,输入,来自pl外部
.ep_empty( ep_empty ),//外部引脚,输入,来自pl外部
.match( match_o ),//与存储仲裁模块有关,本地产生,输入。match_o = !pid_bad & token_valid & !crc5_err
.nse_err( nse_err ),//外壳引脚,输出
.int_upid_set( int_upid_set ),//Set unsupported PID interrupt
//好象根本没有用到,外壳引脚,输出,搞清他们输出给谁
.int_crc16_set( int_crc16_set ),//外壳引脚,输出
.int_to_set( int_to_set ),//外壳引脚,输出
.int_seqerr_set( int_seqerr_set ),//外壳引脚,输出
.csr( csr ),//外部引脚,输入
.send_stall( send_stall )//外壳引脚,输入,他们来自何方??
);
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -