参考设计,module dma_ctrl

该模块为DMA控制器,主要负责处理系统输入、AXI主接口数据传输、转换8b/64b数据,并与外部设备如cpld交互。通过状态机实现控制,包括数据接收、转换、发送等功能,同时具有超时管理和错误处理机制。
摘要由CSDN通过智能技术生成


`timescale 1 ns / 1 ns

module dma_ctrl (
//system
input           iclk,
input           irst,

//axi_master
output  [71:0]  dma_data,    //{wr_rd,adrs[31:0]}-sop-data-eop
output          dma_den,
input           dma_ready,

input   [71:0]  cpld_data,
input           cpld_en,

//transform_8b_64b
input   [71:0]  recomb_data_2sw,
input   [71:0]  recomb_data_2host,
input   [71:0]  recomb_data_2arm,
input           recomb_den_2sw,
input           recomb_den_2host,
input           recomb_den_2arm,
//output  [2:0]   recomb_buf_ready,

//send to ge port
output  [71:0]  down_data,
output          down_den_H,
output          down_den_L,
input           down_buf_ready_H,
input           down_buf_ready_L,

//host_reg
input           iline0_en,
input   [19:0]  iline0_data_baseadrs,
input   [19:0]  iline0_mesg_baseadrs,
input   [19:0]  iline0_fpgawr_point_baseadrs,
input   [1:0]   iline0_depth_define,
input   [7:0]   iline0_mesg_toutcfg,
input   [9:0]   iline0_cpu_point,
output  [9:0]   oline0_fpga_point,

input           iline1_en,
input   [19:0]  iline1_data_baseadrs,
input   [19:0]  iline1_mesg_baseadrs,
input   [19:0]  iline1_fpgawr_point_baseadrs,
input   [1:0]   iline1_depth_define,
input   [7:0]   iline1_mesg_toutcfg,
input   [9:0]   iline1_cpu_point,
output  [9:0]   oline1_fpga_point,

input           iline2_en,
input   [19:0]  iline2_data_baseadrs,
input   [19:0]  iline2_mesg_baseadrs,
input   [19:0]  iline2_fpgawr_point_baseadrs,
input   [1:0]   iline2_depth_define,
input   [7:0]   iline2_mesg_toutcfg,
input   [9:0]   iline2_cpu_point,
output  [9:0]   oline2_fpga_point,

input           iline3_en,
input   [19:0]  iline3_data_baseadrs,
input   [19:0]  iline3_mesg_baseadrs,
input   [19:0]  iline3_fpgawr_point_baseadrs,
input   [1:0]   iline3_depth_define,
input   [7:0]   iline3_mesg_toutcfg,
input   [9:0]   iline3_cpu_point,
output  [9:0]   oline3_fpga_point,

input           iline4_en,
input   [19:0]  iline4_data_baseadrs,
input   [19:0]  iline4_mesg_baseadrs,
input   [19:0]  iline4_fpgawr_point_baseadrs,
input   [1:0]   iline4_depth_define,
input   [7:0]   iline4_mesg_toutcfg,
input   [9:0]   iline4_cpu_point,
output  [9:0]   oline4_fpga_point,

//debug
output  reg [31:0]  dma_pulse,
output  reg [31:0]  dma_state
);

//  define

//  timeout pulse
reg     [7:0]   time_cycle_cnt;
reg             time_1us_pulse;
reg     [7:0]   line2_msg_tout_cnt;
reg             line2_mesg_tout_pulse;
reg     [9:0]   line2_depth;

//  main control FSM
reg     [1:0]   fsm_dma;
reg     [3:0]   ch_index;
reg     [7:0]   fsm_opt_cnt;
wire            prepare_ch_sel;
wire            done_ch_sel;

//  receive transform_8b_64b data
wire    [71:0]  dataw_dout_line0;
wire    [71:0]  dataw_dout_line1;
wire    [71:0]  dataw_dout_line2;
wire    [12:0]  dataw_hout_line0;
wire    [12:0]  dataw_hout_line1;
wire    [12:0]  dataw_hout_line2;
wire    [2:0]   dataw_rdready;
wire    [2:0]   datawr_drop_pls;
reg     [9:0]   line0_dataw_point;
reg     [9:0]   line1_dataw_point;
reg     [9:0]   line2_dataw_point;
reg             line0_is_full;
reg             line1_is_full;
reg             line2_is_full;
reg             prepare_line0_dataw;
reg             prepare_line1_dataw;
reg             prepare_line2_dataw;
reg     [7:0]   dataw_head_len;
reg     [10:0]  dataw_head_bytecnt;
reg     [2:0]   dataw_rdden;
reg     [2:0]   dataw_rdden_d1;
reg     [2:0]   dataw_rdden_d2;
reg     [2:0]   dataw_rdden_d3;
reg     [2:0]   dataw_rdhen;
reg     [2:0]   dataw_rdhen_d1;
reg     [2:0]   dataw_rdhen_d2;
reg     [2:0]   dataw_rdhen_d3;
wire            done_line0_dataw;
wire            done_line1_dataw;
wire            done_line2_dataw;
reg     [71:0]  mesgw;
reg             mesgw_wen;
reg     [71:0]  dataw_headdata;
reg             dataw_headden;
//  receive message
reg             mesgw_buf_ready;
wire    [71:0]  mesgw_dout_line2;
wire            mesgw_empty_line2;
wire    [9:0]   mesgw_count_line2;
reg             prepare_line0_mesgw;
reg             prepare_line1_mesgw;
reg             prepare_line2_mesgw;
reg     [31:0]  line012_mesg_optadrs;
reg     [10:0]  num_mesgw_bottom;
reg     [10:0]  num_mesgw_4KB;
reg     [10:0]  num_mesgw_fifo;
reg     [10:0]  num_mesgw_act;
reg     [10:0]  line012_mesgw_optleng;
//read control
reg             mesgw_opt_en;
reg     [10:0]  mesgw_rdcnt;
reg             done_line012_mesgw;
reg             mesgw_ren;
wire            mesgw_headen;

//  refresh mesg_wr_point
reg             done_line012_mesgw_d1;
reg             done_line012_refresh;
reg     [9:0]   line0_mesgwr_point;
reg     [9:0]   line1_mesgwr_point;
reg     [9:0]   line2_mesgwr_point;
reg             refresh_line_en_sel;
reg             dma_data_refresh_en;
reg     [71:0]  dma_data_refresh;
//  read line-tx message
reg             prepare_line3_mesgr;
reg             prepare_line4_mesgr;
reg     [10:0]  num_mesgr_bottom;
reg     [10:0]  num_mesgr_4KB;
reg     [10:0]  num_mesgr_linedepth;
reg     [10:0]  num_mesgr_act;
reg     [31:0]  line34_mesg_optadrs;
reg     [10:0]  line34_mesg_optleng;
reg             line3_mesg_opten;
reg             line4_mesg_opten;
reg     [9:0]   line3_mesgrd_point;
reg     [9:0]   line4_mesgrd_point;
reg             mesg_rd_ing_line3;
reg             mesg_rd_ing_line4;
wire            done_line3_mesgr;
wire            done_line4_mesgr;
reg             mesgr_buf_ready_line3;
reg             mesgr_buf_ready_line4;
wire    [1:0]   cpld_port;
wire    [71:0]  mesgr_dout_line3;
wire            mesgr_empty_line3;
wire    [9:0]   mesgr_count_line3;
wire    [71:0]  mesgr_dout_line4;
wire            mesgr_empty_line4;
wire    [9:0]   mesgr_count_line4;
//  read line-tx data
reg             prepare_line3_datar;
reg             prepare_line4_datar;
reg     [31:0]  line34_data_optadrs;
reg     [10:0]  line34_data_optleng;
reg             line3_data_opten;
reg             line4_data_opten;
reg     [9:0]   line3_datard_point;
reg             cplded_line3_datar;
reg     [9:0]   line4_datard_point;
reg             cplded_line4_datar;
reg             data_rd_ing_line3;
reg             data_rd_ing_line4;
wire            done_line3_datar;
wire            mesgr_ren_line3;
wire            done_line4_datar;
wire            mesgr_ren_line4;
reg     [71:0]  down_data_r;
reg             down_den_r_H;
reg             down_den_r_L;
//  output control
reg     [71:0]  dma_data_r;
reg             dma_den_r;


//  main control - FSM

//  timeout pulse
always @ (posedge iclk)begin
    if(irst)begin
        time_cycle_cnt <= 8'b0;
        time_1us_pulse <= 1'b0;
        line2_msg_tout_cnt <= 8'b0;
        line2_mesg_tout_pulse <= 1'b0;
    end else begin
        time_cycle_cnt <= time_cycle_cnt + 1'b1;
        time_1us_pulse <= (time_cycle_cnt==8'hFF)?1'b1:1'b0;    //256*5ns=1.2us
        if(time_1us_pulse==1'b1)begin
            line2_msg_tout_cnt <= (line2_msg_tout_cnt==iline2_mesg_toutcfg)?8'h0:(line2_msg_tout_cnt+1'b1);
        end
        if(time_1us_pulse==1'b1)begin   //default:1.2us*0x80=0.15ms
            line2_mesg_tout_pulse <= (line2_msg_tout_cnt==iline2_mesg_toutcfg)?1'b1:1'b0;
        end else begin
            line2_mesg_tout_pulse <= 1'b0;
        end
    end
end

//line depth
always @ (posedge iclk)begin
    line2_depth <=  (iline2_depth_define==2'b11)?10'h3ff:
                    (iline2_depth_define==2'b10)?10'h1ff:
                    (iline2_depth_define==2'b01)?10'h0ff:10'h07f;
end

//  main control FSM
parameter   F_IDLE  = 2'h0;
parameter   F_OPT   = 2'h1;

always @ (posedge iclk)begin
    if(irst)begin
        fsm_dma <= F_IDLE;
    end else begin
        case(fsm_dma)
            F_IDLE  :   if(prepare_ch_sel==1'b1 && dma_ready==1'b1)begin
                            fsm_dma <= F_OPT;
                        end
            F_OPT   :   if(done_ch_sel==1'b1)begin
                            fsm_dma <= F_IDLE;
                        end
            default :   fsm_dma <= F_IDLE;
        endcase
    end
end

always @ (posedge iclk)begin
    if(irst)begin
        ch_index <= 4'b0;
    end else begin
        if(fsm_dma==F_IDLE && prepare_ch_sel==1'b0)begin
            ch_index <= (ch_index==4'h9)?4'b0:(ch_index + 1'b1);
        end else if(fsm_dma==F_OPT && done_ch_sel==1'b1)begin
            ch_index <= (ch_index==4'h9)?4'b0:(ch_index + 1'b1);
        end
    end
end

always @ (posedge iclk)begin
    if(fsm_dma==F_OPT)begin
        fsm_opt_cnt <= (fsm_opt_cnt[7:4]==4'hF)?8'hF0:(fsm_opt_cnt+1'b1);
    end else begin
        fsm_opt_cnt <= 8'b0;
    end
end

assign prepare_ch_sel = (ch_index==4'h0) ? prepare_line0_dataw :
                        (ch_index==4'h1) ? prepare_line1_dataw :
                        (ch_index==4'h2) ? prepare_line2_dataw :
                        (ch_index==4'h3) ? prepare_line0_mesgw :
                        (ch_index==4'h4) ? prepare_line1_mesgw :
                        (ch_index==4'h5) ? prepare_line2_mesgw :
                        (ch_index==4'h6) ? prepare_line3_mesgr :
                        (ch_index==4'h7) ? prepare_line4_mesgr :
                        (ch_index==4'h8) ? prepare_line3_datar :
                                           prepare_line4_datar ;

assign done_ch_sel = (ch_index==4'h0) ? done_line0_dataw :
                     (ch_index==4'h1) ? done_line1_dataw :
                     (ch_index==4'h2) ? done_line2_dataw :
                     (ch_index==4'h3) ? done_line012_refresh :
                     (ch_index==4'h4) ? done_line012_refresh :
                     (ch_index==4'h5) ? done_line012_refresh :
                     (ch_index==4'h6) ? done_line3_mesgr :
                     (ch_index==4'h7) ? done_line4_mesgr :
                     (ch_index==4'h8) ? done_line3_datar :
                                        done_line4_datar ;


//  receive transform_8b_64b data

buf_store_forward_w72 buf_line0(
    .sys_clk        (iclk),
    .sys_rst        (irst),
    .wrdata         (recomb_data_2sw),
    .wrdata_eop     (recomb_data_2sw[70]),
    .wrdata_err     (1'b0),
    .wrdata_info    (2'b0),
    .wren           (recomb_den_2sw),
    .wrready        (),
    .rddata         (dataw_dout_line0),
    .rdden          (dataw_rdden[0]),
    .rdhead         (dataw_hout_line0),
    .rdhen          (dataw_rdhen[0]),
    .rdready        (dataw_rdready[0]),
    .wr_drop_pls    (datawr_drop_pls[0])
);
buf_store_forward_w72 buf_line1(
    .sys_clk        (iclk),
    .sys_rst        (irst),
    .wrdata         (recomb_data_2host),
    .wrdata_eop     (recomb_data_2host[70]),
    .wrdata_err     (1'b0),
    .wrdata_info    (2'b0),
    .wren           (recomb_den_2host),
    .wrready        (),
    .rddata         (dataw_dout_line1),
    .rdden          (dataw_rdden[1]),
    .rdhead         (dataw_hout_line1),
    .rdhen          (dataw_rdhen[1]),
    .rdready        (dataw_rdready[1]),
    .wr_drop_pls    (datawr_drop_pls[1])
);
buf_store_forward_w72 buf_line2(
    .sys_clk        (iclk),
    .sys_rst        (irst),
    .wrdata         (recomb_data_2arm),
    .wrdata_eop     (recomb_data_2arm[70]),
    .wrdata_err     (1'b0),
    .wrdata_info    (2'b0),
    .wren           (recomb_den_2arm),
    .wrready        (),
    .rddata         (dataw_dout_line2),
    .rdden          (dataw_rdden[2]),
    .rdhead         (dataw_hout_line2),
    .rdhen          (dataw_rdhen[2]),
    .rdready        (dataw_rdready[2]),
    .wr_drop_pls    (datawr_drop_pls[2])
);

always @ (posedge iclk)begin
    if(iline0_en==1'b0)begin
        line0_dataw_point <= 10'b0;
    end else if(dataw_rdhen[0])begin
        line0_dataw_point <= (line0_dataw_point==line2_depth)?10'b0:(line0_dataw_point+1'b1);
    end
    if(iline1_en==1'b0)begin
        line1_dataw_point <= 10'b0;
    end else if(dataw_rdhen[1])begin
        line1_dataw_point <= (line1_dataw_point==line2_depth)?10'b0:(line1_dataw_point+1'b1);
    end
    if(iline2_en==1'b0)begin
        line2_dataw_point <= 10'b0;
    end else if(dataw_rdhen[2])begin
        line2_dataw_point <= (line2_dataw_point==line2_depth)?10'b0:(line2_dataw_point+1'b1);
    end

    if((line0_dataw_point+1'b1)&line2_depth==iline0_cpu_point)begin
        line0_is_full <= 1'b1;
    end else begin
        line0_is_full <= 1'b0;
    end
    if((line1_dataw_point+1'b1)&line2_depth==iline1_cpu_point)begin
        line1_is_full <= 1'b1;
    end else begin
        line1_is_full <= 1'b0;
    end
    if((line2_dataw_point+1'b1)&line2_depth==iline2_cpu_point)begin
        line2_is_full <= 1'b1;
    end else begin
        line2_is_full <= 1'b0;
    end
    prepare_line0_dataw <= (dataw_rdready[0]==1'b1) & (line0_is_full==1'b0) & (iline0_en==1'b1);
    prepare_line1_dataw <= (dataw_rdready[1]==1'b1) & (line1_is_full==1'b0) & (iline1_en==1'b1);
    prepare_line2_dataw <= (dataw_rdready[2]==1'b1) & (line2_is_full==1'b0) & (iline2_en==1'b1) & (mesgw_buf_ready==1'b1);
end

always @ (posedge iclk)begin
    if(fsm_dma==F_IDLE && ch_index==4'h0)begin
        dataw_head_len <= dataw_hout_line0[10:3];
        dataw_head_bytecnt <= dataw_hout_line0[10:0]+1'b1;
    end else if(fsm_dma==F_IDLE && ch_index==4'h1)begin
        dataw_head_len <= dataw_hout_line1[10:3];
        dataw_head_bytecnt <= dataw_hout_line1[10:0]+1'b1;
    end else if(fsm_dma==F_IDLE && ch_index==4'h2)begin
        dataw_head_len <= dataw_hout_line2[10:3];
        dataw_head_bytecnt <= dataw_hout_line2[10:0]+1'b1;
    end

    dataw_rdden[0] <= (fsm_dma==F_OPT) & (fsm_opt_cnt<=dataw_head_len) & (ch_index==4'h0);
    dataw_rdden[1] <= (fsm_dma==F_OPT) & (fsm_opt_cnt<=dataw_head_len) & (ch_index==4'h1);
    dataw_rdden[2] <= (fsm_dma==F_OPT) & (fsm_opt_cnt<=dataw_head_len) & (ch_index==4'h2);

    dataw_rdhen[0] <= (fsm_dma==F_OPT) & (fsm_opt_cnt==dataw_head_len) & (ch_index==4'h0);
    dataw_rdhen[1] <= (fsm_dma==F_OPT) & (fsm_opt_cnt==dataw_head_len) & (ch_index==4'h1);
    dataw_rdhen[2] <= (fsm_dma==F_OPT) & (fsm_opt_cnt==dataw_head_len) & (ch_index==4'h2);
end

always @ (posedge iclk)begin
    dataw_rdden_d1 <= dataw_rdden;
    dataw_rdden_d2 <= dataw_rdden_d1;
    dataw_rdden_d3 <= dataw_rdden_d2;

    dataw_rdhen_d1 <= dataw_rdhen;
    dataw_rdhen_d2 <= dataw_rdhen_d1;
    dataw_rdhen_d3 <= dataw_rdhen_d2;
end
assign done_line0_dataw = dataw_rdhen_d2[0];
assign done_line1_dataw = dataw_rdhen_d2[1];
assign done_line2_dataw = dataw_rdhen_d2[2];

always @ (posedge iclk)begin
    if(ch_index==4'h2 && fsm_dma==F_OPT && fsm_opt_cnt==8'b0)begin
        mesgw <= {dataw_head_bytecnt,22'b0,line2_dataw_point[9:0]};
        mesgw_wen <= iline2_en;
    end else begin
        mesgw_wen <= 1'b0;
    end
end

always @ (posedge iclk)begin
    if(ch_index==4'h0 && fsm_dma==F_OPT && fsm_opt_cnt==8'b0)begin
        dataw_headdata[71:70] <= 2'b10;
        dataw_headdata[69:43] <= 27&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值