Fri, 13 Aug 2010 10:43:05 +0100
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