HierarchyFilesModulesSignalsTasksFunctionsHelp
Prev12
          hsize     = {1'b0, dst_size_limit};
          hprot3to1 = dst_prot_ctrl;
        end
      `PL230_ST_WR_CTRL:
        begin
          htrans    = `PL230_AHB_TRANS_NONSEQ;
          hwrite    = `PL230_AHB_WRITE;
          hsize     = `PL230_AHB_SIZE_WORD;
          hprot3to1 = chnl_ctrl_hprot3to1;
        end
      `PL230_ST_RESVD_0,
      `PL230_ST_RESVD_1,
      `PL230_ST_RESVD_2,
      `PL230_ST_RESVD_3,
      `PL230_ST_RESVD_4:
        begin
          htrans    = `PL230_AHB_TRANS_IDLE;
          hwrite    = `PL230_AHB_READ;
          hsize     = `PL230_AHB_SIZE_WORD;
          hprot3to1 = chnl_ctrl_hprot3to1;
        end
      default:
        begin
          htrans    = 2'bxx;
          hwrite    = 1'bx;
          hsize     = 2'bxx;
          hprot3to1 = 3'bxxx;
        end
    endcase
  end // p_ahb_ctrl

  // AHB interface protection control
  //  The lsb selects data or opcode fetch
  //  AHB accesses are always classed as data
  assign hprot = {hprot3to1, 1'b1};
  // AHB interface burst length
  //  Only single transactions are supported
  assign hburst = 3'b000;
  // AHB locked access control
  //  Locked accesses are not supported
  assign hmastlock = 1'b0;

  //----------------------------------------------------------------------------
  // Address Calculation
  //----------------------------------------------------------------------------
  // Select source or destination transfer size
  // This is done one cycle ahead of the actual AHB address phase
  assign mux_size = (ctrl_state == `PL230_ST_RD_SDAT) ? dst_size : src_size;
  // Select source or destination address increment
  // This is done one cycle ahead of the actual AHB address phase
  assign mux_inc  = (ctrl_state == `PL230_ST_RD_SDAT) ? dst_inc  : src_inc;

  // Control for the address offset
  always @( mux_size or mux_inc )
  begin : p_ctrl_offset
    case ( mux_size )
      `PL230_SIZE_BYTE:
      begin
        case ( mux_inc )
          2'b00: ctrl_offset = 2'b00;
          2'b01: ctrl_offset = 2'b01;
          2'b10: ctrl_offset = 2'b10;
          2'b11: ctrl_offset = 2'b11;
          default: ctrl_offset = 2'bxx;
        endcase
      end
      `PL230_SIZE_HWORD:
      begin
        case ( mux_inc )
          2'b00: ctrl_offset = 2'b01;
          2'b01: ctrl_offset = 2'b01;
          2'b10: ctrl_offset = 2'b10;
          2'b11: ctrl_offset = 2'b11;
          default: ctrl_offset = 2'bxx;
        endcase
      end
      `PL230_SIZE_WORD:
      begin
        case ( mux_inc )
          2'b00: ctrl_offset = 2'b10;
          2'b01: ctrl_offset = 2'b10;
          2'b10: ctrl_offset = 2'b10;
          2'b11: ctrl_offset = 2'b11;
          default: ctrl_offset = 2'bxx;
        endcase
      end
      `PL230_SIZE_RESVD:
      begin
        case ( mux_inc )
          2'b00: ctrl_offset = 2'b10;
          2'b01: ctrl_offset = 2'b10;
          2'b10: ctrl_offset = 2'b10;
          2'b11: ctrl_offset = 2'b11;
          default: ctrl_offset = 2'bxx;
        endcase
      end
      default:
        ctrl_offset = 2'bxx;
    endcase
  end // p_ctrl_offset

  // Address offset
  always @( ctrl_offset or n_count )
  begin : p_addr_offset
    case ( ctrl_offset )
      2'b00:                             // Address offset - byte
        addr_offset = {2'b00, n_count};
      2'b01:                             // Address offset - halfword
        addr_offset = {1'b0, n_count, 1'b0};
      2'b10:                             // Address offset - word
        addr_offset = {n_count, 2'b00};
      2'b11:                             // Address offset - fixed address
        addr_offset = {`PL230_N_COUNT_BITS+2{1'b0}};
      default:
        addr_offset = {`PL230_N_COUNT_BITS+2{1'bx}};
    endcase
  end // p_addr_offset

  // Address offset fixed for scatter/gather primary channel
  assign addr_offset_sg_pri =
           // If using primary control data for scatter gather
           (((cycle_ctrl == 3'b100) || (cycle_ctrl == 3'b110)) &&
           // and the destination address is being calculated
           (ctrl_state == `PL230_ST_RD_SDAT))
           // only use two bits of N as the same four alternate control data
           // locations must be written to multiple times
           ? {{`PL230_N_COUNT_BITS-2{1'b0}}, n_count[1:0], 2'b00}
           // otherwise use the full address offset
           : addr_offset;

  // Source/Destination end address
  //  Lower bits are masked for word and half-word transfers
  //  to stop the user causing unaligned transfer addresses
  always @( mux_size or hrdata )
  begin : p_src_dst_end_addr
    case ( mux_size )
      2'b00:
        src_dst_end_addr = hrdata;
      2'b01:
        src_dst_end_addr = {hrdata[31:1], 1'b0};
      2'b10:
        src_dst_end_addr = {hrdata[31:2], 2'b00};
      2'b11:
        src_dst_end_addr = {hrdata[31:2], 2'b00};
      default:
        src_dst_end_addr = 32'bxxxx_xxxx;
    endcase
  end // p_src_dst_end_addr

  // DMA data address calculation for source and destination
  assign dma_addr = src_dst_end_addr -
                      {{32-`PL230_N_COUNT_BITS-2{1'b0}}, addr_offset_sg_pri};

  // Channel control data select
  always @( ctrl_state_nxt )
  begin : p_ctrl_dat_sel
    case (ctrl_state_nxt)
      `PL230_ST_RD_CTRL:
        ctrl_dat_sel = 2'b10;
      `PL230_ST_RD_SPTR:
        ctrl_dat_sel = 2'b00;
      `PL230_ST_RD_DPTR:
        ctrl_dat_sel = 2'b01;
      `PL230_ST_WR_CTRL:
        ctrl_dat_sel = 2'b10;
      `PL230_ST_IDLE,
      `PL230_ST_RD_SDAT,
      `PL230_ST_WR_DDAT,
      `PL230_ST_WAIT,
      `PL230_ST_STALL,
      `PL230_ST_DONE,
      `PL230_ST_PSGP,
      `PL230_ST_RESVD_0,
      `PL230_ST_RESVD_1,
      `PL230_ST_RESVD_2,
      `PL230_ST_RESVD_3,
      `PL230_ST_RESVD_4:
        ctrl_dat_sel = 2'b10;
      default:
        ctrl_dat_sel = 2'bxx;
    endcase
  end // p_ctrl_dat_sel

  // Channel control data address calculation
  assign ctrl_dat_addr = {ctrl_base_ptr,
                          |(chnl_pri_alt_status & current_chnl_onehot),
`ifdef PL230_ONE_CHNL
`else
                          current_chnl,
`endif
                          ctrl_dat_sel,
                          2'b00};

  // AHB interface address next value
  assign haddr_nxt = ((data_state == `PL230_ST_RD_SPTR) ||
                      ((data_state == `PL230_ST_RD_DPTR) &&
                       (cycle_ctrl != 3'b000)))
                     ? dma_addr
                     : ctrl_dat_addr;

  // AHB interface address
  always @( negedge hresetn or posedge hclk )
  begin : p_haddr
    if ( hresetn == 1'b0 )
      haddr <= 32'h0000_0000;
    else
      if ( data_state_en )
        haddr <= haddr_nxt;
  end // p_haddr

  //----------------------------------------------------------------------------
  // Two to the power of R counter
  //----------------------------------------------------------------------------
  // 2^R transfers complete
  assign twotor_complete = (twotor_count == {`PL230_N_COUNT_BITS{1'b0}});

  // R forced to zero when dma_sreq is the request source
  //   except for Peripheral Scatter/Gather Primary
  assign r_override = ( override_r && (cycle_ctrl != 3'b110) ) ? 4'b0000 : r;

  // Power of 2 calculation using R in the channel_cfg register
  always @( r_override )
  begin : p_twotor
    case ( r_override )
      4'b0000: twotor = 10'h000;
      4'b0001: twotor = 10'h001;
      4'b0010: twotor = 10'h003;
      4'b0011: twotor = 10'h007;
      4'b0100: twotor = 10'h00f;
      4'b0101: twotor = 10'h01f;
      4'b0110: twotor = 10'h03f;
      4'b0111: twotor = 10'h07f;
      4'b1000: twotor = 10'h0ff;
      4'b1001: twotor = 10'h1ff;
      4'b1010,
      4'b1011,
      4'b1100,
      4'b1101,
      4'b1110,
      4'b1111: twotor = 10'h3ff;
      default: twotor = 10'hxxx;
    endcase
  end // p_twotor

  // 2^R counter enable
  assign twotor_count_en  = twotor_count_load ||             // Load
                            (counter_decrement &&            // Decrement
                              !twotor_complete);

  // 2^R counter load
  assign twotor_count_nxt = twotor_count_load
                            ? twotor                         // Load
                            : twotor_count - 1;              // Decrement

  // 2^R counter
  always @( negedge hresetn or posedge hclk )
  begin : p_twotor_count
    if ( hresetn == 1'b0 )
      twotor_count <= {`PL230_N_COUNT_BITS{1'b0}};
    else
      if ( twotor_count_en )
        twotor_count <= twotor_count_nxt;
  end // p_twotor_count

  //----------------------------------------------------------------------------
  // N counter
  //----------------------------------------------------------------------------
  // N transfers complete enable
  assign n_complete_en  = hready && (data_state == `PL230_ST_RD_SPTR);

  // N transfers complete next value
  assign n_complete_nxt = (n_count == {`PL230_N_COUNT_BITS{1'b0}});

  // N transfers complete
  always @( negedge hresetn or posedge hclk )
  begin : p_n_complete
    if ( hresetn == 1'b0 )
      n_complete <= 1'b0;
    else
      if ( n_complete_en )
        n_complete <= n_complete_nxt;
  end // p_n_complete

  // N counter enable
  assign n_count_en = channel_cfg_load ||                    // Load
                      (counter_decrement &&                  // Decrement
                        !n_complete && !disable_on_slave_err);

  // N counter load
  assign n_count_nxt = channel_cfg_load
                       ? hrdata[`PL230_N_COUNT_BITS-1+`PL230_N_COUNT_OFFSET
                                :`PL230_N_COUNT_OFFSET]           // Load
                       : n_count - 1;                             // Decrement

  // N counter
  always @( negedge hresetn or posedge hclk )
  begin : p_n_count
    if ( hresetn == 1'b0 )
      n_count <= {`PL230_N_COUNT_BITS{1'b0}};
    else
      if ( n_count_en )
        n_count <= n_count_nxt;
  end // p_n_count


endmodule // pl230_ahb_ctrl

`include "pl230_undefs.v"

12
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Wed Nov 16 11:46:43 2022
From: ../../../../../../arm-AAA-ip/DMA-230_MicroDMA_Controller/PL230-BU-00000-r0p0-02rel2/shared/logical/pl230_udma/verilog/pl230_ahb_ctrl.v

Verilog converted to html by v2html 7.30.1.3 (written by Costas Calamvokis).Help