📄 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_RESET
always @(posedge clk or negedge rst)
`else
always @(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 Indicator
always @(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 input
always @(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;
end
always @(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 word
always @(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 Buffers
always @(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];
endcase
assign 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_RESET
always @(posedge clk or negedge rst)
`else
always @(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_RESET
always @(posedge clk or negedge rst)
`else
always @(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_DEBUG
if(rst)
begin
if(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_DEBUG
if(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_DEBUG
if(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_DEBUG
if(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_DEBUG
if(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_DEBUG
if(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_DEBUG
if(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_DEBUG
if(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
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -