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