rtl/verilog/slave_reg.v

Fri, 13 Aug 2010 10:43:05 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 13 Aug 2010 10:43:05 +0100
changeset 0
11aef665a5d8
child 1
522426d22baa
permissions
-rw-r--r--

Initial commit, DMAC version 3.1

     1 // =============================================================================
     2 //                           COPYRIGHT NOTICE
     3 // Copyright 2006 (c) Lattice Semiconductor Corporation
     4 // ALL RIGHTS RESERVED
     5 // This confidential and proprietary software may be used only as authorised by
     6 // a licensing agreement from Lattice Semiconductor Corporation.
     7 // The entire notice above must be reproduced on all authorized copies and
     8 // copies may only be made to the extent permitted by a licensing agreement from
     9 // Lattice Semiconductor Corporation.
    10 //
    11 // Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    12 // 5555 NE Moore Court                            408-826-6000 (other locations)
    13 // Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    14 // U.S.A                                   email: techsupport@latticesemi.com
    15 // =============================================================================/
    16 //                         FILE DETAILS
    17 // Project          : LM32 DMA Component
    18 // File             : slave_reg.v
    19 // Title            : DMA Slave controller 
    20 // Dependencies     : None
    21 // Version          : 7.0
    22 //                  : Initial Release
    23 // Version          : 7.0SP2, 3.0
    24 //   1. Read and Write channel of DMA controller are working in parallel,
    25 //      due to that now as soon as FIFO is not empty write channel of the DMA
    26 //      controller start writing data to the slave.
    27 //   2. Burst Size supported by DMA controller is increased to support bigger
    28 //      burst (from current value of 4 and 8 to 16 and 32). Now 4 different type
    29 //      of burst sizes are supported by the DMA controller 4, 8, 16 and 32. 
    30 //      For this Burst Size field of the control register is increased to 2 bits.
    31 //   3. Glitch is removed on the S_ACK_O signal. 
    32 // Version          : 3.1
    33 //                  : Make DMA Engine compliant to Rule 3.100 of Wishbone Spec
    34 //                  : which defines alignement of bytes in sub-word transfers.
    35 // =============================================================================
    37 `ifndef SLAVE_REG_FILE
    38  `define SLAVE_REG_FILE
    39  `include "system_conf.v"
    40 module SLAVE_REG 
    41   #(parameter LENGTH_WIDTH = 16,
    42     parameter FIFO_IMPLEMENTATION = "EBR")
    43     (
    44      //slave port
    45      S_ADR_I,    //32bits
    46      S_DAT_I,    //32bits
    47      S_WE_I,
    48      S_STB_I,
    49      S_CYC_I,
    50      S_CTI_I,
    51      S_DAT_O,    //32bits
    52      S_ACK_O,
    53      S_INT_O,
    54      //Master Address
    55 //      MA_SEL_O,
    56 //      MB_SEL_O,
    57      M_SEL_O,
    58      //internal signals
    59      reg_start,
    60      reg_status,
    61      reg_interrupt,
    62      reg_busy,
    63      data_length,
    64      reg_cntlg,
    65      reg_bt2,reg_bt1,reg_bt0,
    66      incr_unit,
    67      reg_s_con,
    68      reg_d_con,
    69      reg_00_data,
    70      reg_04_data,
    71      //system clock and reset
    72      CLK_I,
    73      RST_I
    74      );
    76    input [31:0]    S_ADR_I;
    77    input [31:0]    S_DAT_I;    //32bits
    78    input           S_WE_I;
    79    input           S_STB_I;
    80    input           S_CYC_I;
    81    input [2:0]     S_CTI_I;
    82    output [31:0]   S_DAT_O;    //32bits
    83    output          S_ACK_O;
    84    output          S_INT_O;    //interrupt signal
    85    //Master Address
    86    output [3:0] M_SEL_O;
    87 //    output [3:0]    MA_SEL_O;
    88 //    output [3:0]    MB_SEL_O;
    89    //internal signals
    90    output          reg_start;
    91    input           reg_status;
    92    input           reg_interrupt;
    93    input           reg_busy;
    94    output [LENGTH_WIDTH-1:0] data_length;
    95    input                     reg_cntlg;
    96    output                    reg_bt2,reg_bt1,reg_bt0;
    97    output [2:0]              incr_unit;
    98    output                    reg_s_con;
    99    output                    reg_d_con;
   100    output [31:0]             reg_00_data;
   101    output [31:0]             reg_04_data;
   103    //system clock and reset
   104    input                     CLK_I;
   105    input                     RST_I;
   107    parameter                 UDLY = 1;
   109    reg [31:0]                reg_00_data;
   110    reg [31:0]                reg_04_data;
   111    reg [LENGTH_WIDTH-1:0]    reg_08_data;
   112    reg [6:0]                 reg_0c_data;
   114    reg [3:0]                 M_SEL_O;
   115 //    wire [3:0]                MA_SEL_O    = M_SEL_O;
   116 //    wire [3:0]                MB_SEL_O    = M_SEL_O;
   117    wire [LENGTH_WIDTH-1:0]   data_length    = reg_08_data;
   119    wire                      reg_bt2, reg_bt1, reg_bt0, reg_incw, reg_inchw, reg_d_con, reg_s_con;
   120    assign                    {reg_bt2,reg_bt1,reg_bt0,reg_incw,reg_inchw,reg_d_con,reg_s_con} = reg_0c_data;
   121    wire [2:0]                incr_unit = reg_incw ? 4 : reg_inchw ? 2 : 1;
   123    wire [8:0]                burst_incr_unit = reg_bt2 ? (reg_bt1 ? (reg_bt0 ? incr_unit<<5 : incr_unit<<4) : (reg_bt0 ? incr_unit<<3 : incr_unit<<2)) : incr_unit;
   124    reg                       reg_ie;
   125    wire [2:0]                read_10_data    = {reg_status,reg_ie,reg_busy};
   127    wire                      reg_wr_rd    = S_CYC_I && S_STB_I;
   129    wire                      master_idle = !reg_busy;
   130    reg                       s_ack_o_pre;
   131    wire                      S_ACK_O    = s_ack_o_pre  && S_CYC_I && S_STB_I;
   133    always @(posedge CLK_I or posedge RST_I)
   134      if(RST_I)
   135        s_ack_o_pre         <= #UDLY 1'b0;
   136      else if(((master_idle && reg_wr_rd) || (!master_idle && reg_wr_rd && !S_WE_I)) && (!s_ack_o_pre)) 
   137        s_ack_o_pre         <= #UDLY 1'b1;
   138      else	     
   139        s_ack_o_pre         <= #UDLY 1'b0;
   142    //register write and read
   143    wire                      reg_wr          = reg_wr_rd && S_WE_I && master_idle && S_ACK_O;
   144    wire                      reg_rd          = reg_wr_rd && !S_WE_I && S_ACK_O;
   146    wire                      dw00_cs         = (!(|S_ADR_I[5:2]));
   147    wire                      dw04_cs         = (S_ADR_I[5:2] == 4'h1);
   148    wire                      dw08_cs         = (S_ADR_I[5:2] == 4'h2);
   149    wire                      dw0c_cs         = (S_ADR_I[5:2] == 4'h3);
   150    wire                      dw10_cs         = (S_ADR_I[5:2] == 4'h4);
   152    //S_DAT_O
   153    wire [31:0]               S_DAT_O = dw00_cs ? reg_00_data :
   154                              dw04_cs ? reg_04_data :
   155                              dw08_cs ? reg_08_data :
   156                              dw0c_cs ? {24'h0,1'h0,reg_0c_data} :
   157                              dw10_cs ? {24'h0,5'h0,read_10_data} : 32'h0;
   159    always @(posedge CLK_I or posedge RST_I)
   160      if(RST_I)
   161        M_SEL_O             <= #UDLY 4'h0;
   162      else if(data_length < incr_unit)
   163        case(data_length[2:0])
   164          1:    M_SEL_O     <= #UDLY 4'h8;
   165          2:    M_SEL_O     <= #UDLY 4'hc;
   166          3:    M_SEL_O     <= #UDLY 4'he;
   167          default:M_SEL_O   <= #UDLY 4'hf;
   168        endcase
   169      else
   170        case(incr_unit)
   171          1:    M_SEL_O     <= #UDLY 4'h8;
   172          2:    M_SEL_O     <= #UDLY 4'hc;
   173          4:    M_SEL_O     <= #UDLY 4'hf;
   174          default:M_SEL_O   <= #UDLY 4'hf;
   175        endcase
   176    //interrupt
   177    reg                       S_INT_O;
   178    always @(posedge CLK_I or posedge RST_I)
   179      if(RST_I)
   180        S_INT_O             <= #UDLY 1'b0;
   181      else if(reg_interrupt && reg_ie)
   182        S_INT_O             <= #UDLY 1'b1;
   183      else if(dw10_cs && reg_rd)
   184        S_INT_O             <= #UDLY 1'b0;
   186    //reg_00
   187    always @(posedge CLK_I or posedge RST_I)
   188      if(RST_I)
   189        reg_00_data         <= #UDLY 32'h0;
   190      else if(dw00_cs && reg_wr)
   191        reg_00_data         <= #UDLY S_DAT_I;
   193    //reg_04
   194    always @(posedge CLK_I or posedge RST_I)
   195      if(RST_I)
   196        reg_04_data         <= #UDLY 32'h0;
   197      else if(dw04_cs && reg_wr)
   198        reg_04_data         <= #UDLY S_DAT_I;
   200    //reg_08
   201    always @(posedge CLK_I or posedge RST_I)
   202      if(RST_I)
   203        reg_08_data         <= #UDLY 32'h0;
   204      else if(reg_cntlg)
   205        reg_08_data         <= #UDLY (reg_08_data < burst_incr_unit) ? 'h0 : (reg_08_data - burst_incr_unit);
   206      else if(dw08_cs && reg_wr)
   207        reg_08_data         <= #UDLY S_DAT_I;
   209    //reg_0c
   210    always @(posedge CLK_I or posedge RST_I)
   211      if(RST_I)
   212        reg_0c_data         <= #UDLY 7'h0;
   213      else if(dw0c_cs && reg_wr)
   214        reg_0c_data         <= #UDLY S_DAT_I[6:0];
   216    //reg_10
   217    reg                       reg_start;
   218    always @(posedge CLK_I or posedge RST_I)
   219      if(RST_I)
   220        begin
   221           reg_ie           <= #UDLY 1'b0;
   222           reg_start        <= #UDLY 1'b0;
   223        end 
   224      else if(dw10_cs && reg_wr) 
   225        begin
   226           reg_ie           <= #UDLY S_DAT_I[1];
   227           reg_start        <= #UDLY S_DAT_I[3];
   228        end 
   229      else 
   230        begin
   231           reg_start        <= #UDLY 1'b0;
   232        end
   233 endmodule // SLAVE_REG
   234 `endif // SLAVE_REG_FILE