OpenCores
URL https://opencores.org/ocsvn/hssdrc/hssdrc/trunk

Subversion Repositories hssdrc

[/] [hssdrc/] [trunk/] [rtl/] [hssdrc_arbiter_out.v] - Rev 3

Compare with Previous | Blame | View Log

//
// Project      : High-Speed SDRAM Controller with adaptive bank management and command pipeline
// 
// Project Nick : HSSDRC
// 
// Version      : 1.0-beta 
//  
// Revision     : $Revision: 1.1 $ 
// 
// Date         : $Date: 2008-03-06 13:52:43 $ 
// 
// Workfile     : hssdrc_arbiter_out.v
// 
// Description  : output 3 way decode arbiter
// 
// HSSDRC is licensed under MIT License
// 
// Copyright (c) 2007-2008, Denis V.Shekhalev (des00@opencores.org) 
// 
// Permission  is hereby granted, free of charge, to any person obtaining a copy of
// this  software  and  associated documentation files (the "Software"), to deal in
// the  Software  without  restriction,  including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the  Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// 
// The  above  copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR  A  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT  HOLDERS  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN  AN  ACTION  OF  CONTRACT,  TORT  OR  OTHERWISE,  ARISING  FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
 
 
`include "hssdrc_timescale.vh"
 
`include "hssdrc_define.vh"
 
module hssdrc_arbiter_out (
  clk                , 
  reset              , 
  sclr               ,                       
  //
  dec0_pre_all       , 
  dec0_refr          , 
  dec0_pre           , 
  dec0_act           , 
  dec0_read          , 
  dec0_write         , 
  dec0_pre_all_enable, 
  dec0_refr_enable   , 
  dec0_pre_enable    , 
  dec0_act_enable    , 
  dec0_read_enable   , 
  dec0_write_enable  , 
  dec0_locked        , 
  dec0_last          , 
  dec0_rowa          , 
  dec0_cola          , 
  dec0_ba            , 
  dec0_chid          , 
  dec0_burst         , 
  //
  dec1_pre_all       , 
  dec1_refr          , 
  dec1_pre           , 
  dec1_act           , 
  dec1_read          , 
  dec1_write         , 
  dec1_pre_all_enable, 
  dec1_refr_enable   , 
  dec1_pre_enable    , 
  dec1_act_enable    , 
  dec1_read_enable   , 
  dec1_write_enable  , 
  dec1_locked        , 
  dec1_last          , 
  dec1_rowa          , 
  dec1_cola          , 
  dec1_ba            , 
  dec1_chid          , 
  dec1_burst         , 
  //
  dec2_pre_all       , 
  dec2_refr          , 
  dec2_pre           , 
  dec2_act           , 
  dec2_read          , 
  dec2_write         , 
  dec2_pre_all_enable, 
  dec2_refr_enable   , 
  dec2_pre_enable    , 
  dec2_act_enable    , 
  dec2_read_enable   , 
  dec2_write_enable  , 
  dec2_locked        , 
  dec2_last          , 
  dec2_rowa          , 
  dec2_cola          , 
  dec2_ba            , 
  dec2_chid          , 
  dec2_burst         , 
  //
  am_pre_all_enable  , 
  am_refr_enable     ,
  am_pre_enable      ,
  am_act_enable      ,
  am_read_enable     ,
  am_write_enable    ,
  //                 
  arb_pre_all        ,
  arb_refr           ,
  arb_pre            ,
  arb_act            ,
  arb_read           ,
  arb_write          ,
  arb_rowa           ,
  arb_cola           ,
  arb_ba             ,
  arb_chid           ,
  arb_burst    
  );
 
  input wire clk  ;
  input wire reset;
  input wire sclr ;
 
  //-------------------------------------------------------------------------------------------------- 
  // interface from sequence decoders 
  //-------------------------------------------------------------------------------------------------- 
 
  input  wire           dec0_pre_all       ;   
  input  wire           dec0_refr          ;   
  input  wire           dec0_pre           ;   
  input  wire           dec0_act           ;   
  input  wire           dec0_read          ;   
  input  wire           dec0_write         ;   
  output logic          dec0_pre_all_enable;
  output logic          dec0_refr_enable   ;
  output logic          dec0_pre_enable    ;
  output logic          dec0_act_enable    ;
  output logic          dec0_read_enable   ;
  output logic          dec0_write_enable  ;
  input  wire           dec0_locked        ;     
  input  wire           dec0_last          ;     
  input  rowa_t         dec0_rowa          ;     
  input  cola_t         dec0_cola          ;     
  input  ba_t           dec0_ba            ;     
  input  chid_t         dec0_chid          ;     
  input  sdram_burst_t  dec0_burst         ; 
  //
  input  wire           dec1_pre_all       ;   
  input  wire           dec1_refr          ;   
  input  wire           dec1_pre           ;   
  input  wire           dec1_act           ;   
  input  wire           dec1_read          ;   
  input  wire           dec1_write         ;   
  output logic          dec1_pre_all_enable;
  output logic          dec1_refr_enable   ;
  output logic          dec1_pre_enable    ;
  output logic          dec1_act_enable    ;
  output logic          dec1_read_enable   ;
  output logic          dec1_write_enable  ;
  input  wire           dec1_locked        ;     
  input  wire           dec1_last          ;     
  input  rowa_t         dec1_rowa          ;     
  input  cola_t         dec1_cola          ;     
  input  ba_t           dec1_ba            ;     
  input  chid_t         dec1_chid          ;     
  input  sdram_burst_t  dec1_burst         ;
  //
  input  wire           dec2_pre_all       ;   
  input  wire           dec2_refr          ;   
  input  wire           dec2_pre           ;   
  input  wire           dec2_act           ;   
  input  wire           dec2_read          ;   
  input  wire           dec2_write         ;   
  output logic          dec2_pre_all_enable;
  output logic          dec2_refr_enable   ;
  output logic          dec2_pre_enable    ;
  output logic          dec2_act_enable    ;
  output logic          dec2_read_enable   ;
  output logic          dec2_write_enable  ;
  input  wire           dec2_locked        ;     
  input  wire           dec2_last          ;     
  input  rowa_t         dec2_rowa          ;     
  input  cola_t         dec2_cola          ;     
  input  ba_t           dec2_ba            ;     
  input  chid_t         dec2_chid          ;     
  input  sdram_burst_t  dec2_burst         ;
 
  //-------------------------------------------------------------------------------------------------- 
  // interface from access manager 
  //-------------------------------------------------------------------------------------------------- 
 
  input wire       am_pre_all_enable  ;
  input wire       am_refr_enable     ;
  input wire [0:3] am_pre_enable      ;
  input wire [0:3] am_act_enable      ;
  input wire [0:3] am_read_enable     ;
  input wire [0:3] am_write_enable    ;
 
  //-------------------------------------------------------------------------------------------------- 
  // interface to multiplexer 
  //-------------------------------------------------------------------------------------------------- 
 
  output logic         arb_pre_all  ;
  output logic         arb_refr     ;
  output logic         arb_pre      ;
  output logic         arb_act      ;
  output logic         arb_read     ;
  output logic         arb_write    ;
  output rowa_t        arb_rowa     ;
  output cola_t        arb_cola     ;
  output ba_t          arb_ba       ;
  output chid_t        arb_chid     ;
  output sdram_burst_t arb_burst    ;
 
  //-------------------------------------------------------------------------------------------------- 
  // 
  //-------------------------------------------------------------------------------------------------- 
  enum bit [1:0] {ARB0, ARB1, ARB2} arb, ba_rowa_mux;  
 
  logic       arb_ack; 
 
  logic       dec0_access_enable;
  logic       dec1_access_enable;
  logic       dec2_access_enable;
 
  logic       dec0_bank_access_enable;
  logic       dec1_bank_access_enable;
  logic       dec2_bank_access_enable;
 
  logic dec1_can_have_access_when_arb_is_0  ;
  logic dec2_can_have_access_when_arb_is_0  ; 
 
  logic dec2_can_have_access_when_arb_is_1  ;  
  logic dec0_can_have_access_when_arb_is_1  ; 
 
  logic dec0_can_have_access_when_arb_is_2  ;  
  logic dec1_can_have_access_when_arb_is_2  ; 
 
  logic       dec0_access_done; 
  logic       dec1_access_done; 
  logic       dec2_access_done; 
 
  //-------------------------------------------------------------------------------------------------- 
  // 
  //-------------------------------------------------------------------------------------------------- 
 
  always_ff @(posedge clk or posedge reset) begin : arbiter_logic 
    if (reset)
      arb <= ARB0; 
    else if (sclr) 
      arb <= ARB0; 
    else if (arb_ack) 
      unique case (arb)
        ARB0 : arb <= ARB1; 
        ARB1 : arb <= ARB2; 
        ARB2 : arb <= ARB0;
      endcase 
  end 
 
  //
  //
  //
  `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
    // use act command sharing 
    assign dec0_bank_access_enable = (dec0_pre & am_pre_enable [dec0_ba] ) |
                                     (dec0_act & am_act_enable [dec0_ba] ) ;
 
    assign dec1_bank_access_enable = (dec1_pre & am_pre_enable [dec1_ba] ) |
                                     (dec1_act & am_act_enable [dec1_ba] ) ;
 
    assign dec2_bank_access_enable = (dec2_pre & am_pre_enable [dec2_ba] ) |
                                     (dec2_act & am_act_enable [dec2_ba] ) ;
  `else 
    // not use act command sharing
    assign dec0_bank_access_enable = (dec0_pre & am_pre_enable [dec0_ba] ) ;
 
    assign dec1_bank_access_enable = (dec1_pre & am_pre_enable [dec1_ba] ) ;
 
    assign dec2_bank_access_enable = (dec2_pre & am_pre_enable [dec2_ba] ) ;
  `endif 
  //
  // 
  // 
  assign dec0_access_enable = (dec0_read   & am_read_enable   [dec0_ba] ) | 
                              (dec0_write  & am_write_enable  [dec0_ba] ) |
                              (dec0_pre    & am_pre_enable    [dec0_ba] ) |
                              (dec0_act    & am_act_enable    [dec0_ba] ) ;
 
  assign dec1_access_enable = (dec1_read   & am_read_enable   [dec1_ba] ) | 
                              (dec1_write  & am_write_enable  [dec1_ba] ) | 
                              (dec1_pre    & am_pre_enable    [dec1_ba] ) |
                              (dec1_act    & am_act_enable    [dec1_ba] ) ;
 
 
  assign dec2_access_enable = (dec2_read   & am_read_enable   [dec2_ba] ) | 
                              (dec2_write  & am_write_enable  [dec2_ba] ) | 
                              (dec2_pre    & am_pre_enable    [dec2_ba] ) |
                              (dec2_act    & am_act_enable    [dec2_ba] ) ;
  //
  //
  //
  assign dec0_access_done   = (dec0_refr  & dec0_refr_enable) | 
                              (dec0_last & 
                                ((dec0_read  & dec0_read_enable  ) | 
                                ( dec0_write & dec0_write_enable ))
                                );
 
  assign dec1_access_done   = (dec1_refr  & dec1_refr_enable) | 
                              (dec1_last & 
                                ((dec1_read  & dec1_read_enable  ) | 
                                ( dec1_write & dec1_write_enable ))
                                );
 
  assign dec2_access_done   = (dec2_refr  & dec2_refr_enable) | 
                              (dec2_last & 
                                ((dec2_read  & dec2_read_enable  ) | 
                                ( dec2_write & dec2_write_enable ))
                                );
  //
  //
  //
  assign arb_ack = (dec0_access_done && (arb == ARB0)) |
                   (dec1_access_done && (arb == ARB1)) |
                   (dec2_access_done && (arb == ARB2));  
  //-------------------------------------------------------------------------------------------------- 
  // decoder roundabout : dec0 -> dec1 -> dec2 -> dec0 -> dec1
  //
  // arbiter for command pipeline need in folow comparators : 
  // 0  : dec0 - dec1 -> select dec1
  //    : dec0 - dec2 & dec1 - dec2 -> select dec2
  // 1  : dec1 - dec2 -> select dec2
  //    : dec1 - dec2 & dec2 - dec0 -> select dec0
  // 2  : dec2 - dec0 -> select dec0
  //    : dec2 - dec1 & dec0 - dec1 -> select dec1
  // we can reclock it. becouse "ba" and "locked" is valid 1 tick before command 
  //-------------------------------------------------------------------------------------------------- 
 
  always_ff @(posedge clk) begin : locked_and_bank_access_comparator
    dec1_can_have_access_when_arb_is_0  <= ~dec0_locked & (dec1_ba != dec0_ba);
    dec2_can_have_access_when_arb_is_0  <= ~dec0_locked & (dec2_ba != dec0_ba) & ~dec1_locked & (dec2_ba != dec1_ba);
 
    dec2_can_have_access_when_arb_is_1  <= ~dec1_locked & (dec2_ba != dec1_ba); 
    dec0_can_have_access_when_arb_is_1  <= ~dec1_locked & (dec0_ba != dec1_ba) & ~dec2_locked & (dec0_ba != dec2_ba); 
 
    dec0_can_have_access_when_arb_is_2  <= ~dec2_locked & (dec0_ba != dec2_ba);  
    dec1_can_have_access_when_arb_is_2  <= ~dec2_locked & (dec1_ba != dec2_ba) & ~dec0_locked & (dec1_ba != dec0_ba);
  end 
 
  //
  //
  //
 
  always_comb begin : control_path_arbiter 
 
    dec0_pre_all_enable = 1'b0;
    dec0_refr_enable    = 1'b0;
    dec0_pre_enable     = 1'b0;
    dec0_act_enable     = 1'b0;
    dec0_read_enable    = 1'b0;
    dec0_write_enable   = 1'b0;
 
    dec1_pre_all_enable = 1'b0;
    dec1_refr_enable    = 1'b0;
    dec1_pre_enable     = 1'b0;
    dec1_act_enable     = 1'b0;
    dec1_read_enable    = 1'b0;
    dec1_write_enable   = 1'b0;
 
    dec2_pre_all_enable = 1'b0;
    dec2_refr_enable    = 1'b0;
    dec2_pre_enable     = 1'b0;
    dec2_act_enable     = 1'b0;
    dec2_read_enable    = 1'b0;
    dec2_write_enable   = 1'b0;
 
    arb_pre_all = 1'b0;    
    arb_refr    = 1'b0;    
    arb_pre     = 1'b0;    
    arb_act     = 1'b0;    
    arb_read    = 1'b0;    
    arb_write   = 1'b0; 
 
    ba_rowa_mux = arb; 
 
    unique case (arb)
      ARB0 : begin : dec0_is_master 
 
        dec0_pre_all_enable = am_pre_all_enable             ;
        dec0_refr_enable    = am_refr_enable                ;
        dec0_pre_enable     = am_pre_enable     [dec0_ba];
        dec0_act_enable     = am_act_enable     [dec0_ba];
        dec0_read_enable    = am_read_enable    [dec0_ba];
        dec0_write_enable   = am_write_enable   [dec0_ba];
 
        arb_pre_all = dec0_pre_all & dec0_pre_all_enable ;
        arb_refr    = dec0_refr    & dec0_refr_enable    ;
        arb_pre     = dec0_pre     & dec0_pre_enable     ;
        arb_act     = dec0_act     & dec0_act_enable     ;
        arb_read    = dec0_read    & dec0_read_enable    ;
        arb_write   = dec0_write   & dec0_write_enable   ;
 
`ifndef HSSDRC_SHARE_NONE_DECODER        
 
        if (~dec0_access_enable) begin 
 
          if (dec1_can_have_access_when_arb_is_0) begin 
 
            ba_rowa_mux = ARB1; 
            //            
            dec1_pre_enable  = am_pre_enable [dec1_ba];
 
            arb_pre          = dec1_pre & dec1_pre_enable ;
            //
            `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND 
              dec1_act_enable  = am_act_enable [dec1_ba];   
 
              arb_act          = dec1_act & dec1_act_enable ;
            `endif
 
          end 
 
    `ifndef HSSDRC_SHARE_ONE_DECODER 
          if (~dec1_bank_access_enable & dec2_can_have_access_when_arb_is_0) begin 
    `else 
          else if (dec2_can_have_access_when_arb_is_0) begin
    `endif 
            ba_rowa_mux = ARB2; 
            //
            dec2_pre_enable  = am_pre_enable [dec2_ba];
 
            arb_pre          = dec2_pre & dec2_pre_enable ;
            // 
            `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
              dec2_act_enable  = am_act_enable [dec2_ba];   
 
              arb_act          = dec2_act & dec2_act_enable ;
            `endif 
 
          end 
        end 
`endif // HSSDRC_SHARE_NONE_DECODER
      end 
 
      ARB1 : begin : dec1_is_master
 
        dec1_pre_all_enable = am_pre_all_enable             ;
        dec1_refr_enable    = am_refr_enable                ;
        dec1_pre_enable     = am_pre_enable     [dec1_ba];
        dec1_act_enable     = am_act_enable     [dec1_ba];
        dec1_read_enable    = am_read_enable    [dec1_ba];
        dec1_write_enable   = am_write_enable   [dec1_ba];
 
        arb_pre_all = dec1_pre_all & dec1_pre_all_enable ;
        arb_refr    = dec1_refr    & dec1_refr_enable    ;
        arb_pre     = dec1_pre     & dec1_pre_enable     ;
        arb_act     = dec1_act     & dec1_act_enable     ;
        arb_read    = dec1_read    & dec1_read_enable    ;
        arb_write   = dec1_write   & dec1_write_enable   ;
 
`ifndef HSSDRC_SHARE_NONE_DECODER        
 
        if (~dec1_access_enable) begin 
 
          if (dec2_can_have_access_when_arb_is_1) begin 
 
            ba_rowa_mux = ARB2;
            //
            dec2_pre_enable  = am_pre_enable   [dec2_ba];
 
            arb_pre          = dec2_pre & dec2_pre_enable ; 
            //
            `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
              dec2_act_enable  = am_act_enable   [dec2_ba];  
 
              arb_act          = dec2_act & dec2_act_enable ; 
            `endif 
 
          end 
 
    `ifndef HSSDRC_SHARE_ONE_DECODER
          if (~dec2_bank_access_enable & dec0_can_have_access_when_arb_is_1) begin 
    `else 
          else if (dec0_can_have_access_when_arb_is_1) begin
    `endif
            ba_rowa_mux = ARB0;
            //
            dec0_pre_enable  = am_pre_enable   [dec0_ba];
 
            arb_pre          = dec0_pre & dec0_pre_enable ; 
            // 
            `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
              dec0_act_enable  = am_act_enable   [dec0_ba]; 
 
              arb_act          = dec0_act & dec0_act_enable ; 
            `endif 
 
          end 
        end 
`endif // HSSDRC_SHARE_NONE_DECODER
      end 
 
      ARB2 : begin : dec2_is_master
 
        dec2_pre_all_enable = am_pre_all_enable               ;
        dec2_refr_enable    = am_refr_enable                  ;
        dec2_pre_enable     = am_pre_enable     [dec2_ba]  ;
        dec2_act_enable     = am_act_enable     [dec2_ba]  ;
        dec2_read_enable    = am_read_enable    [dec2_ba]  ;
        dec2_write_enable   = am_write_enable   [dec2_ba]  ;
 
        arb_pre_all = dec2_pre_all & dec2_pre_all_enable ;
        arb_refr    = dec2_refr    & dec2_refr_enable    ;
        arb_pre     = dec2_pre     & dec2_pre_enable     ;
        arb_act     = dec2_act     & dec2_act_enable     ;
        arb_read    = dec2_read    & dec2_read_enable    ;
        arb_write   = dec2_write   & dec2_write_enable   ;
 
`ifndef HSSDRC_SHARE_NONE_DECODER
 
        if (~dec2_access_enable) begin 
 
          if (dec0_can_have_access_when_arb_is_2) begin 
 
            ba_rowa_mux = ARB0; 
            //
            dec0_pre_enable  = am_pre_enable   [dec0_ba];
 
            arb_pre          = dec0_pre & dec0_pre_enable ;
            //
            `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
              dec0_act_enable  = am_act_enable   [dec0_ba];
 
              arb_act          = dec0_act & dec0_act_enable ;
            `endif 
 
          end 
 
    `ifndef HSSDRC_SHARE_ONE_DECODER
          if (~dec0_bank_access_enable & dec1_can_have_access_when_arb_is_2) begin 
    `else 
          else if (dec1_can_have_access_when_arb_is_2) begin
    `endif 
            ba_rowa_mux = ARB1;
            //
            dec1_pre_enable  = am_pre_enable   [dec1_ba];
 
            arb_pre          = dec1_pre & dec1_pre_enable  ;
            //
            `ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
              dec1_act_enable  = am_act_enable   [dec1_ba];    
 
              arb_act          = dec1_act & dec1_act_enable  ;
            `endif
 
          end 
        end 
`endif // HSSDRC_SHARE_NONE_DECODER
      end 
    endcase 
  end 
 
 
 
  always_comb begin : mux_addr_path2arbiter 
 
    //
    // no complex mux : used in read/write command 
    //
 
    arb_cola   = dec0_cola; 
    arb_chid   = dec0_chid;
    arb_burst  = dec0_burst; 
 
    unique case (arb) 
      ARB0 : begin 
        arb_cola   = dec0_cola;
        arb_chid   = dec0_chid;
        arb_burst  = dec0_burst; 
        end 
      ARB1 : begin 
        arb_cola   = dec1_cola;
        arb_chid   = dec1_chid;
        arb_burst  = dec1_burst; 
        end 
      ARB2 : begin 
        arb_cola   = dec2_cola;      
        arb_chid   = dec2_chid;
        arb_burst  = dec2_burst; 
        end 
      default : begin end 
    endcase
 
    //
    // complex mux used in pre command
    //
 
    arb_ba     = dec0_ba;  
 
    unique case (ba_rowa_mux) 
      ARB0 : arb_ba = dec0_ba; 
      ARB1 : arb_ba = dec1_ba; 
      ARB2 : arb_ba = dec2_ba; 
    endcase 
 
    //
    // complex mux used in act command
    //
 
    arb_rowa   = dec0_rowa;
 
`ifndef HSSDRC_NOT_SHARE_ACT_COMMAND
      unique case (ba_rowa_mux) 
`else 
      unique case (arb) 
`endif 
      ARB0 : arb_rowa = dec0_rowa;  
      ARB1 : arb_rowa = dec1_rowa;  
      ARB2 : arb_rowa = dec2_rowa;  
    endcase
 
  end 
 
endmodule 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.