rtl/verilog/slave_reg.v

changeset 0
11aef665a5d8
child 1
522426d22baa
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/rtl/verilog/slave_reg.v	Fri Aug 13 10:43:05 2010 +0100
     1.3 @@ -0,0 +1,234 @@
     1.4 +// =============================================================================
     1.5 +//                           COPYRIGHT NOTICE
     1.6 +// Copyright 2006 (c) Lattice Semiconductor Corporation
     1.7 +// ALL RIGHTS RESERVED
     1.8 +// This confidential and proprietary software may be used only as authorised by
     1.9 +// a licensing agreement from Lattice Semiconductor Corporation.
    1.10 +// The entire notice above must be reproduced on all authorized copies and
    1.11 +// copies may only be made to the extent permitted by a licensing agreement from
    1.12 +// Lattice Semiconductor Corporation.
    1.13 +//
    1.14 +// Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    1.15 +// 5555 NE Moore Court                            408-826-6000 (other locations)
    1.16 +// Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    1.17 +// U.S.A                                   email: techsupport@latticesemi.com
    1.18 +// =============================================================================/
    1.19 +//                         FILE DETAILS
    1.20 +// Project          : LM32 DMA Component
    1.21 +// File             : slave_reg.v
    1.22 +// Title            : DMA Slave controller 
    1.23 +// Dependencies     : None
    1.24 +// Version          : 7.0
    1.25 +//                  : Initial Release
    1.26 +// Version          : 7.0SP2, 3.0
    1.27 +//   1. Read and Write channel of DMA controller are working in parallel,
    1.28 +//      due to that now as soon as FIFO is not empty write channel of the DMA
    1.29 +//      controller start writing data to the slave.
    1.30 +//   2. Burst Size supported by DMA controller is increased to support bigger
    1.31 +//      burst (from current value of 4 and 8 to 16 and 32). Now 4 different type
    1.32 +//      of burst sizes are supported by the DMA controller 4, 8, 16 and 32. 
    1.33 +//      For this Burst Size field of the control register is increased to 2 bits.
    1.34 +//   3. Glitch is removed on the S_ACK_O signal. 
    1.35 +// Version          : 3.1
    1.36 +//                  : Make DMA Engine compliant to Rule 3.100 of Wishbone Spec
    1.37 +//                  : which defines alignement of bytes in sub-word transfers.
    1.38 +// =============================================================================
    1.39 +
    1.40 +`ifndef SLAVE_REG_FILE
    1.41 + `define SLAVE_REG_FILE
    1.42 + `include "system_conf.v"
    1.43 +module SLAVE_REG 
    1.44 +  #(parameter LENGTH_WIDTH = 16,
    1.45 +    parameter FIFO_IMPLEMENTATION = "EBR")
    1.46 +    (
    1.47 +     //slave port
    1.48 +     S_ADR_I,    //32bits
    1.49 +     S_DAT_I,    //32bits
    1.50 +     S_WE_I,
    1.51 +     S_STB_I,
    1.52 +     S_CYC_I,
    1.53 +     S_CTI_I,
    1.54 +     S_DAT_O,    //32bits
    1.55 +     S_ACK_O,
    1.56 +     S_INT_O,
    1.57 +     //Master Address
    1.58 +//      MA_SEL_O,
    1.59 +//      MB_SEL_O,
    1.60 +     M_SEL_O,
    1.61 +     //internal signals
    1.62 +     reg_start,
    1.63 +     reg_status,
    1.64 +     reg_interrupt,
    1.65 +     reg_busy,
    1.66 +     data_length,
    1.67 +     reg_cntlg,
    1.68 +     reg_bt2,reg_bt1,reg_bt0,
    1.69 +     incr_unit,
    1.70 +     reg_s_con,
    1.71 +     reg_d_con,
    1.72 +     reg_00_data,
    1.73 +     reg_04_data,
    1.74 +     //system clock and reset
    1.75 +     CLK_I,
    1.76 +     RST_I
    1.77 +     );
    1.78 +
    1.79 +   input [31:0]    S_ADR_I;
    1.80 +   input [31:0]    S_DAT_I;    //32bits
    1.81 +   input           S_WE_I;
    1.82 +   input           S_STB_I;
    1.83 +   input           S_CYC_I;
    1.84 +   input [2:0]     S_CTI_I;
    1.85 +   output [31:0]   S_DAT_O;    //32bits
    1.86 +   output          S_ACK_O;
    1.87 +   output          S_INT_O;    //interrupt signal
    1.88 +   //Master Address
    1.89 +   output [3:0] M_SEL_O;
    1.90 +//    output [3:0]    MA_SEL_O;
    1.91 +//    output [3:0]    MB_SEL_O;
    1.92 +   //internal signals
    1.93 +   output          reg_start;
    1.94 +   input           reg_status;
    1.95 +   input           reg_interrupt;
    1.96 +   input           reg_busy;
    1.97 +   output [LENGTH_WIDTH-1:0] data_length;
    1.98 +   input                     reg_cntlg;
    1.99 +   output                    reg_bt2,reg_bt1,reg_bt0;
   1.100 +   output [2:0]              incr_unit;
   1.101 +   output                    reg_s_con;
   1.102 +   output                    reg_d_con;
   1.103 +   output [31:0]             reg_00_data;
   1.104 +   output [31:0]             reg_04_data;
   1.105 +
   1.106 +   //system clock and reset
   1.107 +   input                     CLK_I;
   1.108 +   input                     RST_I;
   1.109 +
   1.110 +   parameter                 UDLY = 1;
   1.111 +
   1.112 +   reg [31:0]                reg_00_data;
   1.113 +   reg [31:0]                reg_04_data;
   1.114 +   reg [LENGTH_WIDTH-1:0]    reg_08_data;
   1.115 +   reg [6:0]                 reg_0c_data;
   1.116 +
   1.117 +   reg [3:0]                 M_SEL_O;
   1.118 +//    wire [3:0]                MA_SEL_O    = M_SEL_O;
   1.119 +//    wire [3:0]                MB_SEL_O    = M_SEL_O;
   1.120 +   wire [LENGTH_WIDTH-1:0]   data_length    = reg_08_data;
   1.121 +
   1.122 +   wire                      reg_bt2, reg_bt1, reg_bt0, reg_incw, reg_inchw, reg_d_con, reg_s_con;
   1.123 +   assign                    {reg_bt2,reg_bt1,reg_bt0,reg_incw,reg_inchw,reg_d_con,reg_s_con} = reg_0c_data;
   1.124 +   wire [2:0]                incr_unit = reg_incw ? 4 : reg_inchw ? 2 : 1;
   1.125 +
   1.126 +   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;
   1.127 +   reg                       reg_ie;
   1.128 +   wire [2:0]                read_10_data    = {reg_status,reg_ie,reg_busy};
   1.129 +
   1.130 +   wire                      reg_wr_rd    = S_CYC_I && S_STB_I;
   1.131 +
   1.132 +   wire                      master_idle = !reg_busy;
   1.133 +   reg                       s_ack_o_pre;
   1.134 +   wire                      S_ACK_O    = s_ack_o_pre  && S_CYC_I && S_STB_I;
   1.135 +   
   1.136 +   always @(posedge CLK_I or posedge RST_I)
   1.137 +     if(RST_I)
   1.138 +       s_ack_o_pre         <= #UDLY 1'b0;
   1.139 +     else if(((master_idle && reg_wr_rd) || (!master_idle && reg_wr_rd && !S_WE_I)) && (!s_ack_o_pre)) 
   1.140 +       s_ack_o_pre         <= #UDLY 1'b1;
   1.141 +     else	     
   1.142 +       s_ack_o_pre         <= #UDLY 1'b0;
   1.143 +
   1.144 +
   1.145 +   //register write and read
   1.146 +   wire                      reg_wr          = reg_wr_rd && S_WE_I && master_idle && S_ACK_O;
   1.147 +   wire                      reg_rd          = reg_wr_rd && !S_WE_I && S_ACK_O;
   1.148 +
   1.149 +   wire                      dw00_cs         = (!(|S_ADR_I[5:2]));
   1.150 +   wire                      dw04_cs         = (S_ADR_I[5:2] == 4'h1);
   1.151 +   wire                      dw08_cs         = (S_ADR_I[5:2] == 4'h2);
   1.152 +   wire                      dw0c_cs         = (S_ADR_I[5:2] == 4'h3);
   1.153 +   wire                      dw10_cs         = (S_ADR_I[5:2] == 4'h4);
   1.154 +
   1.155 +   //S_DAT_O
   1.156 +   wire [31:0]               S_DAT_O = dw00_cs ? reg_00_data :
   1.157 +                             dw04_cs ? reg_04_data :
   1.158 +                             dw08_cs ? reg_08_data :
   1.159 +                             dw0c_cs ? {24'h0,1'h0,reg_0c_data} :
   1.160 +                             dw10_cs ? {24'h0,5'h0,read_10_data} : 32'h0;
   1.161 +
   1.162 +   always @(posedge CLK_I or posedge RST_I)
   1.163 +     if(RST_I)
   1.164 +       M_SEL_O             <= #UDLY 4'h0;
   1.165 +     else if(data_length < incr_unit)
   1.166 +       case(data_length[2:0])
   1.167 +         1:    M_SEL_O     <= #UDLY 4'h8;
   1.168 +         2:    M_SEL_O     <= #UDLY 4'hc;
   1.169 +         3:    M_SEL_O     <= #UDLY 4'he;
   1.170 +         default:M_SEL_O   <= #UDLY 4'hf;
   1.171 +       endcase
   1.172 +     else
   1.173 +       case(incr_unit)
   1.174 +         1:    M_SEL_O     <= #UDLY 4'h8;
   1.175 +         2:    M_SEL_O     <= #UDLY 4'hc;
   1.176 +         4:    M_SEL_O     <= #UDLY 4'hf;
   1.177 +         default:M_SEL_O   <= #UDLY 4'hf;
   1.178 +       endcase
   1.179 +   //interrupt
   1.180 +   reg                       S_INT_O;
   1.181 +   always @(posedge CLK_I or posedge RST_I)
   1.182 +     if(RST_I)
   1.183 +       S_INT_O             <= #UDLY 1'b0;
   1.184 +     else if(reg_interrupt && reg_ie)
   1.185 +       S_INT_O             <= #UDLY 1'b1;
   1.186 +     else if(dw10_cs && reg_rd)
   1.187 +       S_INT_O             <= #UDLY 1'b0;
   1.188 +
   1.189 +   //reg_00
   1.190 +   always @(posedge CLK_I or posedge RST_I)
   1.191 +     if(RST_I)
   1.192 +       reg_00_data         <= #UDLY 32'h0;
   1.193 +     else if(dw00_cs && reg_wr)
   1.194 +       reg_00_data         <= #UDLY S_DAT_I;
   1.195 +
   1.196 +   //reg_04
   1.197 +   always @(posedge CLK_I or posedge RST_I)
   1.198 +     if(RST_I)
   1.199 +       reg_04_data         <= #UDLY 32'h0;
   1.200 +     else if(dw04_cs && reg_wr)
   1.201 +       reg_04_data         <= #UDLY S_DAT_I;
   1.202 +
   1.203 +   //reg_08
   1.204 +   always @(posedge CLK_I or posedge RST_I)
   1.205 +     if(RST_I)
   1.206 +       reg_08_data         <= #UDLY 32'h0;
   1.207 +     else if(reg_cntlg)
   1.208 +       reg_08_data         <= #UDLY (reg_08_data < burst_incr_unit) ? 'h0 : (reg_08_data - burst_incr_unit);
   1.209 +     else if(dw08_cs && reg_wr)
   1.210 +       reg_08_data         <= #UDLY S_DAT_I;
   1.211 +
   1.212 +   //reg_0c
   1.213 +   always @(posedge CLK_I or posedge RST_I)
   1.214 +     if(RST_I)
   1.215 +       reg_0c_data         <= #UDLY 7'h0;
   1.216 +     else if(dw0c_cs && reg_wr)
   1.217 +       reg_0c_data         <= #UDLY S_DAT_I[6:0];
   1.218 +
   1.219 +   //reg_10
   1.220 +   reg                       reg_start;
   1.221 +   always @(posedge CLK_I or posedge RST_I)
   1.222 +     if(RST_I)
   1.223 +       begin
   1.224 +          reg_ie           <= #UDLY 1'b0;
   1.225 +          reg_start        <= #UDLY 1'b0;
   1.226 +       end 
   1.227 +     else if(dw10_cs && reg_wr) 
   1.228 +       begin
   1.229 +          reg_ie           <= #UDLY S_DAT_I[1];
   1.230 +          reg_start        <= #UDLY S_DAT_I[3];
   1.231 +       end 
   1.232 +     else 
   1.233 +       begin
   1.234 +          reg_start        <= #UDLY 1'b0;
   1.235 +       end
   1.236 +endmodule // SLAVE_REG
   1.237 +`endif // SLAVE_REG_FILE