OpenCores
URL https://opencores.org/ocsvn/next186mp3/next186mp3/trunk

Subversion Repositories next186mp3

[/] [next186mp3/] [trunk/] [HW/] [DSP32.v] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ndumitrach
`timescale 1ns / 1ps
2
 
3
//////////////////////////////////////////////////////////////////////////////////
4
//
5
// This file is part of the Next186 Soc PC project
6
// http://opencores.org/project,next186
7
//
8
// Filename: DSP32.v
9
// Description: Part of the Next186 SoC PC project, DSP coprocessor
10
// Version 1.0
11
// Creation date: Jan2015
12
//
13
// Author: Nicolae Dumitrache 
14
// e-mail: ndumitrache@opencores.org
15
//
16
/////////////////////////////////////////////////////////////////////////////////
17
// 
18
// Copyright (C) 2012 Nicolae Dumitrache
19
// 
20
// This source file may be used and distributed without 
21
// restriction provided that this copyright statement is not 
22
// removed from the file and that any derivative work contains 
23
// the original copyright notice and the associated disclaimer.
24
// 
25
// This source file is free software; you can redistribute it 
26
// and/or modify it under the terms of the GNU Lesser General 
27
// Public License as published by the Free Software Foundation;
28
// either version 2.1 of the License, or (at your option) any 
29
// later version. 
30
// 
31
// This source is distributed in the hope that it will be 
32
// useful, but WITHOUT ANY WARRANTY; without even the implied 
33
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
34
// PURPOSE. See the GNU Lesser General Public License for more 
35
// details. 
36
// 
37
// You should have received a copy of the GNU Lesser General 
38
// Public License along with this source; if not, download it 
39
// from http://www.opencores.org/lgpl.shtml 
40
// 
41
///////////////////////////////////////////////////////////////////////////////////
42
// Additional Comments: 
43
//
44
// 8 x 64integers overlapping data windows, over 256 integers 
45
// command: 16'b0c000vvvvvvvvvvv = set r/w pointer - 256 32bit integers, 2048 instructions. c=1 for code write, 0 for data read/write
46
// command: 16'b10wwwvvvvvvvvvvv = run ip - 2048 instructions, 3 bit data window offset
47
//
48
// Instructions:
49
// D=dest(0..63), S=src(0..63)
50
//      0 - MOV D,S [mov 0,0 = HALT, mov 8,8..mov 15,15 = set data window, other mov x,x = NOP, CF unaffected]
51
// 1 - SAR D,n  [n[2:0] = shift arythmetic right 1..8, CF <- D[0]]
52
//      2 - ADD D,S
53
//      3 - ADC D,S
54
// 4 - SUB D,S
55
// 5 - SBB D,S
56
// 6 - MULH D,S [{D, CF} <- D*S >> 32]
57
// 7 - MULL D,S [{D, CF} <- D*S]
58
// 8 - MULM      D,S    [{D, CF} <- D*S >> 16]
59
// 9 - TOWORD D,S [D <- {WORD(D), WORD(S)}, CF unaffected] 
60
// 10- SHR D,n [n[2:0] = shift logic right 1..8, CF enters through left, CF <- D[0]]
61
// 11- AND D, S [CF <- 1]
62
// 12- OR D, S  [CF <- (D | S) != 0]
63
// 13- XOR D, S [CF <- !CF]
64
//////////////////////////////////////////////////////////////////////////////////
65
 
66
module DSP32(
67
                input clk,
68
                input cmd,
69
                input ce,
70
                input wr,
71
                input [15:0]din,
72
                output [15:0]dout,
73
                output reg halt
74
);
75
 
76
        reg [10:0]rwp = 0;        // read/write pointer
77
        reg [10:0]ip = 0;  // instruction pointer
78
        reg [2:0]dwin = 0; // data window
79
        reg [2:0]dwin1 = 0;
80
        reg hi = 0;
81
        reg [15:0]lodata;
82
        reg [31:0]res;
83
        reg wcode = 0;
84
        reg CF; // carry flag
85
        reg [2:0]op;
86
        wire [15:0]instr;
87
        reg [15:0]instr1;
88
        reg run = 1'b0;
89
        reg mc;
90
        wire signed [31:0]D;
91
        wire signed [31:0]S;
92
        wire cin = (instr1[14] ^ (CF & instr1[12]));
93
        wire [32:0]sumdiff = D + ({32{instr1[14]}} ^ S) + cin;
94
        wire signed [63:0]mul = D * S;
95
        wire [15:0]S16 = (~|S[31:15] | &S[31:15]) ? S[15:0] : {S[31], {15{!S[31]}}};
96
        wire [15:0]D16 = (~|D[31:15] | &D[31:15]) ? D[15:0] : {D[31], {15{!D[31]}}};
97
        wire extwrite = ce && wr && !cmd && hi && !wcode;
98
 
99
        assign ihalt = ~|instr;
100
 
101
        instrmem Code
102
        (
103
          .clka(clk), // input clka
104
          .wea(ce && !cmd && wcode && wr), // input [0 : 0] wea
105
          .addra(rwp), // input [10 : 0] addra
106
          .dina(din), // input [15 : 0] dina
107
          .clkb(clk), // input clkb
108
          .enb(run || (!ihalt && !extwrite)),
109
          .addrb(ip), // input [10 : 0] addrb
110
          .doutb(instr) // output [15 : 0] doutb
111
        );
112
 
113
        regs DSRegs
114
        (
115
                .clk(clk),
116
                .we(!halt || extwrite),
117
                .rd(!extwrite),
118
                .wa(extwrite ? rwp[7:0] : {dwin1 + instr1[11], instr1[10:6]}),
119
                .din(extwrite ? {din, lodata} : res),
120
                .rda({dwin + instr[11], instr[10:6]}),
121
                .D(D),
122
                .rsa({dwin + instr[5], instr[4:0]}),
123
                .S(S),
124
                .rra({rwp[7:0], hi}),
125
                .dout(dout)
126
        );
127
 
128
        always @(op, S, D, S16, D16, instr1, sumdiff, mul) begin
129
                mc = 1'bx;
130
                case(op)
131
                        0: res = S;
132
                        1: res =  $signed({instr1[12] ? D[31] : CF, D[30:0]}) >>> (instr1[2:0] + 1);
133
                        2: res = sumdiff[31:0];
134
                        3: {res, mc} = {mul, 1'b0} >> (instr1[15] ? 16 : instr1[12] ? 0 : 32);
135
                        4: res = {D16, S16};
136
                        5: res = S & D;
137
                        6: res = S | D;
138
                        7: res = S ^ D;
139
                endcase
140
        end
141
 
142
 
143
        always @(posedge clk) begin
144
 
145
                if(ce)
146
                        if(cmd) begin
147
                                if(wr && !din[15]) {hi, wcode, rwp} <= {1'b0, din[14], din[10:0]};       // set rwp
148
                        end else begin
149
                                hi <= !hi;
150
                                lodata <= din;
151
                                if(wcode || hi) rwp <= rwp + 1'b1;
152
                        end
153
 
154
                if(ce && cmd && wr && din[15]) {run, dwin, ip} <= {1'b1, din[13:0]}; // run
155
                else begin
156
                        run <= 1'b0;
157
                        if(!extwrite) begin
158
                                ip <= ip + 1'b1;
159
                                if({instr[15:9], instr[5:3]} == 10'b0000001001) dwin <= instr[2:0];
160
                                dwin1 <= dwin;
161
                        end
162
                end
163
 
164
                if(!extwrite) begin // if not write external data
165
                        halt <= ihalt;
166
                        instr1 <= instr;
167
 
168
                        case(instr[15:12])
169
                                0: op <= 3'b000; // S
170
                                1,10: op <= 3'b001; // SAR, SHR
171
                                2,3,4,5: op <= 3'b010; // adder
172
                                6,7,8: op <= 3'b011; // MULHI, MULLO, MULM
173
                                9: op <= 3'b100; // TOWORD
174
                                11: op <= 3'b101; // AND
175
                                12: op <= 3'b110; // OR
176
                                13: op <= 3'b111; // XOR
177
                                default: op <= 3'bxxx;
178
                        endcase
179
 
180
                        case(op)
181
                                1: CF <= S[0];
182
                                2: CF <= sumdiff[32] ^ instr1[14];
183
                                3: CF <= mc;
184
                                5: CF <= 1'b1;  // and
185
                                6: CF <= |res;  // or
186
                                7: CF <= !CF;   // xor
187
                        endcase
188
 
189
                end
190
        end
191
 
192
endmodule
193
 
194
 
195
module regs(
196
        input clk,
197
        input we,
198
        input rd,
199
        input [7:0]wa,
200
        input [31:0]din,
201
        input [7:0]rda,
202
        output reg [31:0]D,
203
        input [7:0]rsa,
204
        output reg [31:0]S,
205
        input [8:0]rra,
206
        output [15:0]dout
207
);
208
 
209
        reg [31:0]r[255:0];
210
 
211
        datamem16 RdRegs
212
        (
213
          .clka(clk), // input clka
214
          .wea(we), // input [0 : 0] wea
215
          .addra(wa), // input [7 : 0] addra
216
          .dina(din), // input [31 : 0] dina
217
          .clkb(clk), // input clkb
218
          .addrb(rra), // input [8 : 0] addrb
219
          .doutb(dout) // output [15 : 0] doutb);
220
        );
221
 
222
        always @(posedge clk) begin
223
                if(we) r[wa] <= din;
224
                if(rd) D <= /*(we && rda == wa) ? din :*/ r[rda];
225
                if(rd) S <= /*(we && rsa == wa) ? din :*/ r[rsa];
226
        end
227
 
228
endmodule
229
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.