rtl/verilog/slave_reg.v

Sat, 06 Aug 2011 01:48:48 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:48:48 +0100
changeset 1
522426d22baa
parent 0
11aef665a5d8
permissions
-rw-r--r--

Update to LM32 DMA v3.3

+// Version : 3.2
+// : 1. Support for 8/32-bit WISHBONE Data Bus. The Control and
+// : Read/Write Ports can be independently configured.
+// : 2. Support for "retry" on receipt of a WISHBONE RTY. This
+// : retry results in the current burst or classic cycle
+// : being issued again after a retry timeout.
+// : 3. Support for "error" on receipt of a WISHBONE ERR. This
+// : results in the current dma transfer being terminated
+// : and the error is updated within the STATUS CSR.
+// : 4. Support for burst size of 64.
+// :
+// Version : 3.3
+// : Support for MachXO2 added. The MachXO2 only has a FIFO
+// : with separate read/write clocks.

     1 //   ==================================================================
     2 //   >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
     3 //   ------------------------------------------------------------------
     4 //   Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
     5 //   ALL RIGHTS RESERVED 
     6 //   ------------------------------------------------------------------
     7 //
     8 //   IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
     9 //
    10 //   Permission:
    11 //
    12 //      Lattice Semiconductor grants permission to use this code
    13 //      pursuant to the terms of the Lattice Semiconductor Corporation
    14 //      Open Source License Agreement.  
    15 //
    16 //   Disclaimer:
    17 //
    18 //      Lattice Semiconductor provides no warranty regarding the use or
    19 //      functionality of this code. It is the user's responsibility to
    20 //      verify the user’s design for consistency and functionality through
    21 //      the use of formal verification methods.
    22 //
    23 //   --------------------------------------------------------------------
    24 //
    25 //                  Lattice Semiconductor Corporation
    26 //                  5555 NE Moore Court
    27 //                  Hillsboro, OR 97214
    28 //                  U.S.A
    29 //
    30 //                  TEL: 1-800-Lattice (USA and Canada)
    31 //                         503-286-8001 (other locations)
    32 //
    33 //                  web: http://www.latticesemi.com/
    34 //                  email: techsupport@latticesemi.com
    35 //
    36 //   --------------------------------------------------------------------
    37 //                         FILE DETAILS
    38 // Project          : LM32 DMA Component
    39 // File             : slave_reg.v
    40 // Title            : DMA Slave controller 
    41 // Dependencies     : None
    42 //                  :
    43 // Version          : 7.0
    44 //                  : Initial Release
    45 //                  :
    46 // Version          : 7.0SP2, 3.0
    47 //                  : 1. Read and Write channel of DMA controller are working in 
    48 //                  :    parallel, due to that now as soon as FIFO is not empty 
    49 //                  :    write channel of the DMA controller start writing data 
    50 //                  :    to the slave.
    51 //                  : 2. Burst Size supported by DMA controller is increased to 
    52 //                  :    support bigger burst (from current value of 4 and 8 to 
    53 //                  :    16 and 32). Now 4 different type of burst sizes are 
    54 //                  :    supported by the DMA controller 4, 8, 16 and 32. For 
    55 //                  :    this Burst Size field of the control register is 
    56 //                  :    increased to 2 bits.
    57 //                  : 3. Glitch is removed on the S_ACK_O signal. 
    58 //                  :
    59 // Version          : 3.1
    60 //                  : 1. Make DMA Engine compliant to Rule 3.100 of Wishbone Spec 
    61 //                  :    which defines alignement of bytes in sub-word transfers.
    62 //                  : 2. Removed glitch that did not pause the burst write when 
    63 //                  :    the read burst was paused by the "read slave".
    64 //                  :
    65 // Version          : 3.2
    66 //                  : 1. Support for 8/32-bit WISHBONE Data Bus. The Control and
    67 //                  :    Read/Write Ports can be independently configured.
    68 //                  : 2. Support for burst size of 64.
    69 //                  :
    70 // Version          : 3.3
    71 //                  : 1. Interrupt can be release by writing 0 to IE bit in the
    72 //                  :    status register.
    73 // =============================================================================
    75 `ifndef SLAVE_REG_FILE
    76  `define SLAVE_REG_FILE
    77  `include "system_conf.v"
    78 module SLAVE_REG 
    79   #(parameter S_WB_DAT_WIDTH = 32,
    80     parameter S_WB_ADR_WIDTH = 32,
    81     parameter MA_WB_DAT_WIDTH = 32,
    82     parameter MA_WB_ADR_WIDTH = 32,
    83     parameter RETRY_TIMEOUT = 16,
    84     parameter FIFO_IMPLEMENTATION = "EBR")
    85    (
    86     input CLK_I,
    87     input RST_I,
    89     // Slave port
    90     input [S_WB_ADR_WIDTH-1:0] S_ADR_I,
    91     input [S_WB_DAT_WIDTH-1:0] S_DAT_I,
    92     input [S_WB_DAT_WIDTH/8-1:0] S_SEL_I,
    93     input S_WE_I,
    94     input S_STB_I,
    95     input S_CYC_I,
    96     input [2:0] S_CTI_I,
    97     output [S_WB_DAT_WIDTH-1:0] S_DAT_O,
    98     output reg S_ACK_O,
    99     output reg S_INT_O,
   101     output reg reg_start,
   102     input reg_status,
   103     input reg_interrupt,
   104     input reg_busy,
   105     output reg reg_bt3, reg_bt2, reg_bt1, reg_bt0,
   106     output reg reg_s_con, reg_d_con,
   107     output reg reg_incw, reg_inchw,
   108     output reg [7:0] reg_rdelay,
   109     output reg [31:0] reg_00_data,
   110     output reg [31:0] reg_04_data,
   111     output reg [31:0] reg_08_data
   112     );
   114    parameter UDLY = 1;
   116    reg [31:0] 	      reg_00_data_nxt, reg_04_data_nxt, reg_08_data_nxt;
   117    reg [7:0] 	      reg_0c_data, reg_0c_data_nxt;
   119    always @(/*AUTOSENSE*/reg_0c_data)
   120      begin
   121 	//reg_rdelay = reg_0c_data[23:16];
   122 	reg_rdelay = RETRY_TIMEOUT;
   123 	reg_bt3    = reg_0c_data[7];
   124 	reg_bt2    = reg_0c_data[6];
   125 	reg_bt1    = reg_0c_data[5];
   126 	reg_bt0    = reg_0c_data[4];
   127 	reg_incw   = reg_0c_data[3];
   128 	reg_inchw  = reg_0c_data[2];
   129 	reg_d_con  = reg_0c_data[1];
   130 	reg_s_con  = reg_0c_data[0];
   131      end
   133    reg [2:0] read_10_data;
   134    reg 	     reg_ie;
   135    always @(/*AUTOSENSE*/reg_busy or reg_ie or reg_status)
   136      begin
   137 	read_10_data[2] = reg_status;
   138 	read_10_data[1] = reg_ie;
   139 	read_10_data[0] = reg_busy;
   140      end
   142    wire master_idle, reg_wr_rd, reg_wr, reg_rd;
   143    assign master_idle = ~reg_busy;
   144    assign reg_wr_rd   = S_CYC_I & S_STB_I;
   145    assign reg_wr      = reg_wr_rd & master_idle & S_WE_I & S_ACK_O;
   146    assign reg_rd      = reg_wr_rd & ~S_WE_I & S_ACK_O;
   148    reg 	s_ack_o_pre, s_ack_o_pre_nxt;
   149    always @(/*AUTOSENSE*/S_CYC_I or S_STB_I or S_WE_I or master_idle
   150 	    or reg_wr_rd or s_ack_o_pre)
   151      begin
   152 	if ((s_ack_o_pre == 1'b0)
   153 	    && ((master_idle && reg_wr_rd) 
   154 		|| ((master_idle == 1'b0) && reg_wr_rd && (S_WE_I == 1'b0))))
   155 	  s_ack_o_pre_nxt = 1'b1;
   156 	else
   157 	  s_ack_o_pre_nxt = 1'b0;
   159 	S_ACK_O = s_ack_o_pre && S_CYC_I && S_STB_I;
   160      end
   162    always @(posedge CLK_I or posedge RST_I)
   163      if (RST_I)
   164        s_ack_o_pre <= #UDLY 1'b0;
   165      else
   166        s_ack_o_pre <= #UDLY s_ack_o_pre_nxt;
   168    wire dw00_cs, dw04_cs, dw08_cs, dw0c_cs, dw10_cs;
   169    assign dw00_cs = (S_ADR_I[5:2] == 4'h0);
   170    assign dw04_cs = (S_ADR_I[5:2] == 4'h1);
   171    assign dw08_cs = (S_ADR_I[5:2] == 4'h2);
   172    assign dw0c_cs = (S_ADR_I[5:2] == 4'h3);
   173    assign dw10_cs = (S_ADR_I[5:2] == 4'h4);
   175    wire [31:0] S_DAT_O_int = (dw00_cs 
   176 			      ? reg_00_data 
   177 			      : (dw04_cs 
   178 				 ? reg_04_data 
   179 				 : (dw08_cs 
   180 				    ? reg_08_data 
   181 				    : (dw0c_cs 
   182 				       ? {4{reg_0c_data}}
   183 				       : (dw10_cs 
   184 					  ? {4{5'h0,read_10_data}} 
   185 					  : 32'h0)))));
   186    generate
   187       if (S_WB_DAT_WIDTH == 8) begin
   189 	 assign S_DAT_O = ((S_ADR_I[1:0] == 2'b00) 
   190 			   ? S_DAT_O_int[31:24]
   191 			   : ((S_ADR_I[1:0] == 2'b01)
   192 			      ? S_DAT_O_int[23:16]
   193 			      : ((S_ADR_I[1:0] == 2'b10)
   194 				 ? S_DAT_O_int[15:8]
   195 				 : S_DAT_O_int[7:0])));
   197       end
   198       else begin
   200 	 assign S_DAT_O = S_DAT_O_int;
   202       end
   203    endgenerate
   207    // Interrupt
   208    generate
   209       if (S_WB_DAT_WIDTH == 8) begin
   211 	 always @(posedge CLK_I or posedge RST_I)
   212 	   begin
   213 	      if(RST_I)
   214 		S_INT_O <= #UDLY 1'b0;
   215 	      else if(reg_interrupt && reg_ie)
   216 		S_INT_O <= #UDLY 1'b1;
   217 	      else if(dw10_cs && (reg_rd || (reg_wr && (S_DAT_I[1] == 1'b0))))
   218 		S_INT_O <= #UDLY 1'b0;
   219 	   end
   221       end
   222       else begin
   224 	 always @(posedge CLK_I or posedge RST_I)
   225 	   begin
   226 	      if(RST_I)
   227 		S_INT_O <= #UDLY 1'b0;
   228 	      else if(reg_interrupt && reg_ie)
   229 		S_INT_O <= #UDLY 1'b1;
   230 	      else if(dw10_cs && (reg_rd || (reg_wr && (S_DAT_I[25] == 1'b0))))
   231 		S_INT_O <= #UDLY 1'b0;
   232 	   end
   234       end
   235    endgenerate
   237    // reg_00
   238    generate
   239       if (S_WB_DAT_WIDTH == 8) begin
   241 	 always @(/*AUTOSENSE*/S_ADR_I or S_DAT_I or dw00_cs
   242 		  or reg_00_data or reg_wr)
   243 	   begin
   244 	      if (dw00_cs && reg_wr) begin
   245 		 casez (S_ADR_I[1:0])
   246 		   2'b00: reg_00_data_nxt = {                    S_DAT_I[7:0], reg_00_data[23: 0]};
   247 		   2'b01: reg_00_data_nxt = {reg_00_data[31:24], S_DAT_I[7:0], reg_00_data[15: 0]};
   248 		   2'b10: reg_00_data_nxt = {reg_00_data[31:16], S_DAT_I[7:0], reg_00_data[ 7: 0]};
   249 		   2'b11: reg_00_data_nxt = {reg_00_data[31: 8], S_DAT_I[7:0]                    };
   251 		   default:
   252 		     reg_00_data_nxt = reg_00_data;
   253 		 endcase
   254 	      end
   255 	      else
   256 		reg_00_data_nxt = reg_00_data;
   257 	   end
   259       end
   260       else begin
   262 	 always @(/*AUTOSENSE*/S_DAT_I or S_SEL_I or dw00_cs
   263 		  or reg_00_data or reg_wr)
   264 	   begin
   265 	      if (dw00_cs && reg_wr) begin
   266 		 casez (S_SEL_I)
   267 		   4'b1000: reg_00_data_nxt = {                    S_DAT_I[31:24], reg_00_data[23:0]};
   268 		   4'b0100: reg_00_data_nxt = {reg_00_data[31:24], S_DAT_I[23:16], reg_00_data[15:0]};
   269 		   4'b0010: reg_00_data_nxt = {reg_00_data[31:16], S_DAT_I[15: 8], reg_00_data[ 7:0]};
   270 		   4'b0001: reg_00_data_nxt = {reg_00_data[31: 8], S_DAT_I[ 7: 0]                   };
   271 		   4'b1111: reg_00_data_nxt =                      S_DAT_I[31: 0]                    ;
   273 		   default:
   274 		     reg_00_data_nxt = reg_00_data;
   275 		 endcase
   276 	      end
   277 	      else
   278 		reg_00_data_nxt = reg_00_data;
   279 	   end
   281       end
   282    endgenerate
   284    always @(posedge CLK_I or posedge RST_I) 
   285      if (RST_I)
   286        reg_00_data <= #UDLY 32'b0;
   287      else
   288        reg_00_data <= #UDLY reg_00_data_nxt;
   292    // reg_04
   293    generate
   294       if (S_WB_DAT_WIDTH == 8) begin
   296 	 always @(/*AUTOSENSE*/S_ADR_I or S_DAT_I or dw04_cs
   297 		  or reg_04_data or reg_wr)
   298 	   begin
   299 	      if (dw04_cs && reg_wr) begin
   300 		 casez (S_ADR_I[1:0])
   301 		   2'b00: reg_04_data_nxt = {                    S_DAT_I[7:0], reg_04_data[23: 0]};
   302 		   2'b01: reg_04_data_nxt = {reg_04_data[31:24], S_DAT_I[7:0], reg_04_data[15: 0]};
   303 		   2'b10: reg_04_data_nxt = {reg_04_data[31:16], S_DAT_I[7:0], reg_04_data[ 7: 0]};
   304 		   2'b11: reg_04_data_nxt = {reg_04_data[31: 8], S_DAT_I[7:0]                    };
   306 		   default:
   307 		     reg_04_data_nxt = reg_04_data;
   308 		 endcase
   309 	      end
   310 	      else
   311 		reg_04_data_nxt = reg_04_data;
   312 	   end
   314       end
   315       else begin
   317 	 always @(/*AUTOSENSE*/S_DAT_I or S_SEL_I or dw04_cs
   318 		  or reg_04_data or reg_wr)
   319 	   begin
   320 	      if (dw04_cs && reg_wr) begin
   321 		 casez (S_SEL_I)
   322 		   4'b1000: reg_04_data_nxt = {                    S_DAT_I[31:24], reg_04_data[23:0]};
   323 		   4'b0100: reg_04_data_nxt = {reg_04_data[31:24], S_DAT_I[23:16], reg_04_data[15:0]};
   324 		   4'b0010: reg_04_data_nxt = {reg_04_data[31:16], S_DAT_I[15: 8], reg_04_data[ 7:0]};
   325 		   4'b0001: reg_04_data_nxt = {reg_04_data[31: 8], S_DAT_I[ 7: 0]                   };
   326 		   4'b1111: reg_04_data_nxt = {                    S_DAT_I[31: 0]                   };
   328 		   default:
   329 		     reg_04_data_nxt = reg_04_data;
   330 		 endcase
   331 	      end
   332 	      else
   333 		reg_04_data_nxt = reg_04_data;
   334 	   end
   336       end
   337    endgenerate
   339    always @(posedge CLK_I or posedge RST_I)
   340      if (RST_I)
   341        reg_04_data <= #UDLY 32'b0;
   342      else
   343        reg_04_data <= #UDLY reg_04_data_nxt;
   347    // reg_08
   348    generate
   349       if (S_WB_DAT_WIDTH == 8) begin
   351 	 always @(/*AUTOSENSE*/S_ADR_I or S_DAT_I or dw08_cs
   352 		  or reg_08_data or reg_wr)
   353 	   if (dw08_cs && reg_wr) begin
   354 	      casez (S_ADR_I[1:0])
   355 		2'b00: reg_08_data_nxt = {                    S_DAT_I[7:0], reg_08_data[23: 0]};
   356 		2'b01: reg_08_data_nxt = {reg_08_data[31:24], S_DAT_I[7:0], reg_08_data[15: 0]};
   357 		2'b10: reg_08_data_nxt = {reg_08_data[31:16], S_DAT_I[7:0], reg_08_data[ 7: 0]};
   358 		2'b11: reg_08_data_nxt = {reg_08_data[31: 8], S_DAT_I[7:0]                    };
   360 		default:
   361 		  reg_08_data_nxt = reg_08_data;
   362 	      endcase
   363 	   end
   365       end
   366       else begin
   368 	 always @(/*AUTOSENSE*/S_DAT_I or S_SEL_I or dw08_cs
   369 		  or reg_08_data or reg_wr)
   370 	   if (dw08_cs && reg_wr) begin
   371 	      casez (S_SEL_I)
   372 		4'b1000: reg_08_data_nxt = {                    S_DAT_I[31:24], reg_08_data[23:0]};
   373 		4'b0100: reg_08_data_nxt = {reg_08_data[31:24], S_DAT_I[23:16], reg_08_data[15:0]};
   374 		4'b0010: reg_08_data_nxt = {reg_08_data[31:16], S_DAT_I[15: 8], reg_08_data[ 7:0]};
   375 		4'b0001: reg_08_data_nxt = {reg_08_data[31: 8], S_DAT_I[ 7: 0]                   };
   376 		4'b1111: reg_08_data_nxt = {                    S_DAT_I[31: 0]                   };
   378 		default:
   379 		  reg_08_data_nxt = reg_08_data;
   380 	      endcase
   381 	   end
   383       end
   384    endgenerate
   386    always @(posedge CLK_I or posedge RST_I)
   387      if (RST_I)
   388        reg_08_data <= #UDLY 0;
   389      else
   390        reg_08_data <= #UDLY reg_08_data_nxt[31:0];
   394    // reg_0c
   395    generate
   396       if (S_WB_DAT_WIDTH == 8) begin
   398 	 always @(/*AUTOSENSE*/S_DAT_I or dw0c_cs or reg_0c_data
   399 		  or reg_wr)
   400 	   if (dw0c_cs && reg_wr)
   401 	     reg_0c_data_nxt = S_DAT_I[7:0];
   402 	   else
   403 	     reg_0c_data_nxt = reg_0c_data;
   405       end
   406       else begin
   408 	 always @(/*AUTOSENSE*/S_DAT_I or S_SEL_I or dw0c_cs
   409 		  or reg_0c_data or reg_wr)
   410 	   if (dw0c_cs && reg_wr)
   411 	     reg_0c_data_nxt = S_DAT_I[31:24];
   412 	   else
   413 	     reg_0c_data_nxt = reg_0c_data;
   415       end
   416    endgenerate
   418    always @(posedge CLK_I or posedge RST_I)
   419      if (RST_I)
   420        reg_0c_data <= #UDLY 8'b0;
   421      else
   422        reg_0c_data <= #UDLY reg_0c_data_nxt;
   426    // reg_10
   427    reg reg_ie_nxt, reg_start_nxt;
   428    generate
   429       if (S_WB_DAT_WIDTH == 8) begin
   431 	 always @(/*AUTOSENSE*/S_DAT_I or dw10_cs or reg_ie or reg_wr)
   432 	   if (dw10_cs && reg_wr)
   433 	     begin
   434 		reg_ie_nxt    = S_DAT_I[1];
   435 		reg_start_nxt = S_DAT_I[3];
   436 	     end
   437 	   else
   438 	     begin
   439 		reg_ie_nxt    = reg_ie;
   440 		reg_start_nxt = 1'b0;
   441 	     end
   443       end
   444       else begin
   446 	 always @(/*AUTOSENSE*/S_DAT_I or S_SEL_I or dw10_cs or reg_ie
   447 		  or reg_wr)
   448 	   if (dw10_cs && reg_wr)
   449 	     begin
   450 		reg_ie_nxt    = S_DAT_I[25];
   451 		reg_start_nxt = S_DAT_I[27];
   452 	     end
   453 	   else
   454 	     begin
   455 		reg_ie_nxt    = reg_ie;
   456 		reg_start_nxt = 1'b0;
   457 	     end
   459       end
   460    endgenerate
   462    always @(posedge CLK_I or posedge RST_I)
   463      if (RST_I)
   464        begin
   465           reg_ie    <= #UDLY 1'b0;
   466           reg_start <= #UDLY 1'b0;
   467        end
   468      else
   469        begin
   470           reg_ie    <= #UDLY reg_ie_nxt;
   471           reg_start <= #UDLY reg_start_nxt;
   472        end 
   474 endmodule // SLAVE_REG
   475 `endif // SLAVE_REG_FILE