📄 usbf_idma.v
字号:
always @(posedge clk)`endif if(!rst) sizd_c <= 14'h3fff; else if(tx_dma_en || tx_dma_en_r) sizd_c <= size; else if(siz_dec) sizd_c <= sizd_c - 14'h1;assign siz_dec = (rd_first & mack_r) | (rd_next & (sizd_c != 14'h0));assign sizd_is_zero_d = sizd_c == 14'h0;always @(posedge clk) sizd_is_zero <= sizd_is_zero_d;// Size Counter (counting up from zero)`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(posedge clk)`endif if(!rst) sizu_c <= 11'h0; else // Do I need to add "abort" in the next line ??? if(rx_dma_en_r) sizu_c <= 11'h0; else if(siz_inc) sizu_c <= sizu_c + 11'h1;assign siz_inc = rx_data_valid_r;// DMA Done Indicatoralways @(posedge clk) idma_done <= (rx_data_done_r | sizd_is_zero_d); // & !tx_dma_en;/////////////////////////////////////////////////////////////////////// RX Logic//always @(posedge clk) dtmp_sel_r <= dtmp_sel;// Memory data inputalways @(posedge clk) if(dtmp_sel_r) dtmp_r <= mdin; else if(rx_data_valid_r) begin if(adr_cb[1:0] == 2'h0) dtmp_r[07:00] <= rx_data_st_r; if(adr_cb[1:0] == 2'h1) dtmp_r[15:08] <= rx_data_st_r; if(adr_cb[1:0] == 2'h2) dtmp_r[23:16] <= rx_data_st_r; if(adr_cb[1:0] == 2'h3) dtmp_r[31:24] <= rx_data_st_r; endalways @(posedge clk) word_done <= ((adr_cb[1:0] == 2'h3) & rx_data_valid_r) | wr_last;always @(posedge clk) word_done_r <= word_done & !word_done_r;// Store output data and address when we got a wordalways @(posedge clk) if(word_done) dout_r <= dtmp_r;always @(posedge clk) wr_last <= (adr_cb[1:0] != 2'h0) & !rx_data_valid_r & wr_last_en;always @(posedge clk) wr_done_r <= rx_data_done_r;always @(posedge clk) wr_done <= wr_done_r;/////////////////////////////////////////////////////////////////////// TX Logic//// Fill TX Buffersalways @(posedge clk) if(fill_buf0) rd_buf0 <= mdin;always @(posedge clk) if(fill_buf1) rd_buf1 <= mdin;always @(adrb_next or rd_buf0 or rd_buf1) case(adrb_next[2:0]) // synopsys full_case parallel_case 3'h0: tx_data_st = rd_buf0[07:00]; 3'h1: tx_data_st = rd_buf0[15:08]; 3'h2: tx_data_st = rd_buf0[23:16]; 3'h3: tx_data_st = rd_buf0[31:24]; 3'h4: tx_data_st = rd_buf1[07:00]; 3'h5: tx_data_st = rd_buf1[15:08]; 3'h6: tx_data_st = rd_buf1[23:16]; 3'h7: tx_data_st = rd_buf1[31:24]; endcaseassign fill_buf0 = !adr_cw[0] & mack_r;assign fill_buf1 = adr_cw[0] & mack_r;assign adrb_is_3 = adr_cb[1:0] == 2'h3;`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(posedge clk)`endif if(!rst) send_data_r <= 1'b0; else if(rd_first) send_data_r <= 1'b1; else if(((sizd_c==14'h1) && rd_next) || sizd_is_zero_d) send_data_r <= 1'b0;assign send_data = send_data_r | send_zero_length_r;/////////////////////////////////////////////////////////////////////// IDMA Load/Store State Machine//// store incoming data to memory until rx_data done// First pre-fetch data from memory, so that bytes can be stuffed properly`ifdef USBF_ASYNC_RESETalways @(posedge clk or negedge rst)`elsealways @(posedge clk)`endif if(!rst) state <= IDLE; else state <= next_state;always @(state or mack_r or abort or rx_dma_en_r or tx_dma_en_r or sizd_is_zero or wr_last or wr_done or rx_data_done_r2 or rd_next or adrb_is_3 or send_zero_length_r) begin next_state = state; // Default do not change state mreq_d = 1'b0; mwe_d = 1'b0; rd_first = 1'b0; dtmp_sel = 1'b0; wr_last_en = 1'b0; case(state) // synopsys full_case parallel_case IDLE: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered IDLE state (%t)", $time);`endif`ifdef USBF_DEBUGif(rst)beginif(rx_dma_en_r === 1'bx) $display("ERROR: IDMA: IDLE: rx_dma_en_r is unknown. (%t)", $time);if(tx_dma_en_r === 1'bx) $display("ERROR: IDMA: IDLE: tx_dma_en_r is unknown. (%t)", $time);if(abort === 1'bx) $display("ERROR: IDMA: IDLE: abort is unknown. (%t)", $time);end`endif// synopsys translate_on if(rx_dma_en_r && !abort) begin next_state = WAIT_MRD; end if(tx_dma_en_r && !abort && !send_zero_length_r) begin next_state = MEM_RD1; end end WAIT_MRD: // Pre-fetch a word from memory begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered WAIT_MRD state (%t)", $time);`endif`ifdef USBF_DEBUGif(abort === 1'bx) $display("ERROR: IDMA: WAIT_MRD: abort is unknown. (%t)", $time);if(mack_r === 1'bx) $display("ERROR: IDMA: WAIT_MRD: mack_r is unknown. (%t)", $time);`endif// synopsys translate_on if(abort) next_state = IDLE; else if(mack_r) next_state = MEM_WR; else begin dtmp_sel = 1'b1; mreq_d = 1'b1; end end MEM_WR: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered MEM_WR state (%t)", $time);`endif`ifdef USBF_DEBUGif(abort === 1'bx) $display("ERROR: IDMA: MEM_WR: abort is unknown. (%t)", $time);if(rx_data_done_r2 === 1'bx) $display("ERROR: IDMA: MEM_WR: rx_data_done_r2 is unknown. (%t)", $time);`endif// synopsys translate_on mwe_d = 1'b1; if(abort) next_state = IDLE; else if(rx_data_done_r2) begin wr_last_en = 1'b1; next_state = MEM_WR1; end end MEM_WR1: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered MEM_WR1 state (%t)", $time);`endif`ifdef USBF_DEBUGif(abort === 1'bx) $display("ERROR: IDMA: MEM_WR1: abort is unknown. (%t)", $time);if(wr_last === 1'bx) $display("ERROR: IDMA: MEM_WR1: wr_last is unknown. (%t)", $time);if(wr_done === 1'bx) $display("ERROR: IDMA: MEM_WR1: wr_done is unknown. (%t)", $time);`endif// synopsys translate_on mwe_d = 1'b1; wr_last_en = 1'b1; if(abort) next_state = IDLE; else if(wr_last) next_state = MEM_WR2; else if(wr_done) next_state = IDLE; end MEM_WR2: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered MEM_WR2 state (%t)", $time);`endif`ifdef USBF_DEBUGif(mack_r === 1'bx) $display("ERROR: IDMA: MEM_WR2: mack_r is unknown. (%t)", $time);`endif// synopsys translate_on mwe_d = 1'b1; if(mack_r) next_state = IDLE; end MEM_RD1: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered MEM_RD1 state (%t)", $time);`endif`ifdef USBF_DEBUGif(abort === 1'bx) $display("ERROR: IDMA: MEM_RD1: abort is unknown. (%t)", $time);if(mack_r === 1'bx) $display("ERROR: IDMA: MEM_RD1: mack_r is unknown. (%t)", $time);`endif// synopsys translate_on mreq_d = 1'b1; if(mack_r) rd_first = 1'b1; if(abort) next_state = IDLE; else if(mack_r) next_state = MEM_RD2; end MEM_RD2: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered MEM_RD2 state (%t)", $time);`endif`ifdef USBF_DEBUGif(abort === 1'bx) $display("ERROR: IDMA: MEM_RD2: abort is unknown. (%t)", $time);if(mack_r === 1'bx) $display("ERROR: IDMA: MEM_RD2: mack_r is unknown. (%t)", $time);`endif// synopsys translate_on mreq_d = 1'b1; if(abort) next_state = IDLE; else if(mack_r) next_state = MEM_RD3; end MEM_RD3: begin// synopsys translate_off`ifdef USBF_VERBOSE_DEBUG$display("IDMA: Entered MEM_RD3 state (%t)", $time);`endif`ifdef USBF_DEBUGif(abort === 1'bx) $display("ERROR: IDMA: MEM_RD3: abort is unknown. (%t)", $time);if(sizd_is_zero===1'bx) $display("ERROR: IDMA: MEM_RD3: sizd_is_zero is unknown. (%t)", $time);if(adrb_is_3 === 1'bx) $display("ERROR: IDMA: MEM_RD3: adrb_is_3 is unknown. (%t)", $time);if(rd_next === 1'bx) $display("ERROR: IDMA: MEM_RD3: rd_next is unknown. (%t)", $time);`endif// synopsys translate_on if(sizd_is_zero || abort) next_state = IDLE; else if(adrb_is_3 && rd_next) next_state = MEM_RD2; end endcase endendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -