📄 adma_top.v
字号:
//// s_stb_o is asserted when system i/f is connected to peripheral i/f// and p_dreq_i is asserted (or software mode CR[SM] is enabled),// or during load of a descriptor//assign s_stb_o = arb_sel_sys & ((p_dreq_i | cr[`ADMA_CR_SM]) & ~cr[`ADMA_CR_DONE] | loading);//// s_adr_o is connected to AIR or to DPR depending whether loading// descriptor or not//`ifdef ADMA_DESCRIPTORSassign s_adr_o[aw-1:2] = loading ? dpr : air;assign s_adr_o[1:0] = 2'b00;`elseassign s_adr_o[aw-1:2] = air;assign s_adr_o[1:0] = 2'b00;`endif/////////////////////////////////////////////////////////////////////////// Address decoder////// Select DMA registers//assign sel_dma = h_stb_i & p_cyc_o & (`ADMA_MATCH_DMA_BASE);//// Generate write enables for host writes into individual DMA registers//assign hwe_ldr = sel_dma & p_we_o & (`ADMA_MATCH_LDR);assign hwe_cr = sel_dma & p_we_o & (`ADMA_MATCH_CR);`ifdef ADMA_DESCRIPTORSassign hwe_dpr = sel_dma & p_we_o & (`ADMA_MATCH_DPR);`endifassign hwe_air = sel_dma & p_we_o & (`ADMA_MATCH_AIR);//// Read DMA register//always @(ldr or cr or dpr or air or h_adr_i) case (h_adr_i[`ADMA_OFS]) `ADMA_OFS_LDR: dma_reg = {{31-`ADMA_MAXLEN{1'b0}}, ldr}; `ADMA_OFS_CR: dma_reg = {23'b0, cr};`ifdef ADMA_DESCRIPTORS `ADMA_OFS_DPR: dma_reg = dpr;`endif default: dma_reg = air; endcase//// Decrement/increment enables for LDR and AIR registers//assign dec_ldr = ~loading & p_dack_o & ~cr[`ADMA_CR_DONE];assign inc_air = ~loading & p_dack_o & ~cr[`ADMA_CR_DONE] & cr[`ADMA_CR_INC_AIR];/////////////////////////////////////////////////////////////////////////// DMA registers////// Length Decrement Register, Control Register DONE bit//always @(posedge clk_i or posedge rst_i) if (rst_i) begin ldr <= #1 {lw{1'b0}}; cr[`ADMA_CR_DONE] <= #1 1'b0; end else if (hwe_ldr | dwe_ldr) ldr <= #1 {1'b0, p_dat_o[lw-1:0]}; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_DONE] <= #1 p_dat_o[`ADMA_CR_DONE]; else if (dec_ldr) {cr[`ADMA_CR_DONE], ldr[lw-1:0]} <= #1 ldr - 1'b1;//// Control Register: Increment Address Increment Register (INC_AIR) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_INC_AIR] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_INC_AIR] <= #1 p_dat_o[`ADMA_CR_INC_AIR];//// Control Register: Write Mode (WM) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_WM] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_WM] <= #1 p_dat_o[`ADMA_CR_WM];//// Control Register: Enable (EN) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_EN] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_EN] <= #1 p_dat_o[`ADMA_CR_EN];//// err is asserted when transfer on system i/f is completed with s_err_i//assign err = s_err_i & arb_sel_sys;//// Control Register: Error (ERR) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_ERR] <= #1 1'b0; else if (hwe_cr | dwe_cr | err) cr[`ADMA_CR_ERR] <= #1 p_dat_o[`ADMA_CR_ERR] | err;//// Control Register: Enable Done Interrupt (EN_DONEINT) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_EN_DONEINT] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_EN_DONEINT] <= #1 p_dat_o[`ADMA_CR_EN_DONEINT];//// Control Register: Enable Error Interrupt (EN_ERRINT) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_EN_ERRINT] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_EN_ERRINT] <= #1 p_dat_o[`ADMA_CR_EN_ERRINT];//// Control Register: SM bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_SM] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_SM] <= #1 p_dat_o[`ADMA_CR_SM];//// Control Register: Fetch Descriptor (FD) bit//always @(posedge clk_i or posedge rst_i) if (rst_i) cr[`ADMA_CR_FD] <= #1 1'b0; else if (hwe_cr | dwe_cr) cr[`ADMA_CR_FD] <= #1 p_dat_o[`ADMA_CR_FD];//// Descriptor Pointer Register//`ifdef ADMA_DESCRIPTORSalways @(posedge clk_i or posedge rst_i) if (rst_i) dpr <= #1 {aw-2{1'b0}}; else if (hwe_dpr | dwe_dpr) dpr <= #1 p_dat_o[aw-1:2]; else if (inc_dpr) dpr <= #1 dpr + 1'b1;`endif//// Address Increment Register//always @(posedge clk_i or posedge rst_i) if (rst_i) air <= #1 {aw-2{1'b0}}; else if (hwe_air | dwe_air) air <= #1 p_dat_o[aw-1:2]; else if (inc_air) air <= #1 air + 1'b1;/////////////////////////////////////////////////////////////////////////// Fetch Descriptor FSM//`ifdef ADMA_DESCRIPTORSassign inc_dpr = loading & p_dack_o;//// FD FSM//always @(posedge clk_i or posedge rst_i) if (rst_i) begin fd_state <= `ADMA_FDFSM_IDLE; dwe_ldr <= #1 1'b0; dwe_cr <= #1 1'b0; dwe_dpr <= #1 1'b0; dwe_air <= #1 1'b0; loading <= #1 1'b0; end else case (fd_state) `ADMA_FDFSM_IDLE: begin if ((p_dnd_i | cr[`ADMA_CR_DONE]) & cr[`ADMA_CR_FD]) begin fd_state <= #1 `ADMA_FDFSM_LENGTH; dwe_ldr <= #1 1'b1; dwe_cr <= #1 1'b0; dwe_dpr <= #1 1'b0; dwe_air <= #1 1'b0; loading <= #1 1'b1; end end `ADMA_FDFSM_LENGTH: begin if (p_dack_o) begin fd_state <= #1 `ADMA_FDFSM_CTRL; dwe_ldr <= #1 1'b0; dwe_cr <= #1 1'b1; dwe_dpr <= #1 1'b0; dwe_air <= #1 1'b0; loading <= #1 1'b1; end end `ADMA_FDFSM_CTRL: begin if (p_dack_o) begin fd_state <= #1 `ADMA_FDFSM_ADDR; dwe_ldr <= #1 1'b0; dwe_cr <= #1 1'b0; dwe_air <= #1 1'b1; dwe_dpr <= #1 1'b0; loading <= #1 1'b1; end end `ADMA_FDFSM_ADDR: begin if (p_dack_o) begin fd_state <= #1 `ADMA_FDFSM_NEXT; dwe_ldr <= #1 1'b0; dwe_cr <= #1 1'b0; dwe_air <= #1 1'b0; dwe_dpr <= #1 1'b1; loading <= #1 1'b1; end end `ADMA_FDFSM_NEXT: begin if (p_dack_o) begin fd_state <= #1 `ADMA_FDFSM_IDLE; dwe_ldr <= #1 1'b0; dwe_cr <= #1 1'b0; dwe_air <= #1 1'b0; dwe_dpr <= #1 1'b0; loading <= #1 1'b0;// synopsys translate_off #2; $display(" LDR: %h", ldr); $display(" CR: %h", cr); $display(" AIR: %h", air<<2); $display(" DPR: %h", dpr<<2);// synopsys translate_on end end endcase`elseassign dpr = {aw-2{1'b0}};assign dwe_ldr = 1'b0;assign dwe_cr = 1'b0;assign dwe_air = 1'b0;assign dwe_dpr = 1'b0;assign loading = 1'b0;assign inc_dpr = 1'b0;`endif`else//// When ADMA is not implemented, connect host and peripheral interfaces directly//assign p_cyc_o = h_cyc_i;assign p_adr_o = h_adr_i;assign p_dat_o = h_dat_i;assign p_sel_o = h_sel_i;assign p_we_o = h_we_i;assign p_stb_o = h_stb_i;assign p_dack_o = 1'b0;assign h_dat_o = p_dat_i;assign h_ack_o = p_ack_i;assign h_err_o = p_err_i;assign h_inta_o = p_inta_i;//// WISHBONE System Interface is not in use//assign s_cyc_o = 1'b0;assign s_adr_o = {aw{1'b0}};assign s_dat_o = {dw{1'b0}};assign s_sel_o = 4'b0000;assign s_we_o = 1'b0;assign s_stb_o = 1'b0;`endifinitial begin// $display("%m %h", base_dma);// #1 $finish;endendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -