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