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

Subversion Repositories cf_ssp

[/] [cf_ssp/] [web_uploads/] [ssp_first_order.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 root
/*
2
 
3
Copyright (c) 2003 Launchbird Design Systems, Inc.
4
 
5
C test bench for State Space Processor.
6
Demonstrates a first order discrete filter:
7
 
8
  H(z) = Y(z) / X(z) = 0.2 / (1 - 0.8 * (1/z))
9
 
10
  y(k) = 0.2 * x(k) + 0.8 * y(k-1)
11
 
12
State Space Processor is configured for 16-bit data and
13
an 8-bit instruction memory address bus.
14
 
15
*/
16
 
17
#include <stdio.h>
18
#include "cf_ssp_16_8.h"
19
 
20
// State Space Processor Inputs
21
 
22
static unsigned char reset[1];
23
static unsigned char cycle[1];
24
static unsigned char instr_data[2];
25
static unsigned char const_data[2];
26
static unsigned char load_write[1];
27
static unsigned char load_addr[1];
28
static unsigned char load_data[2];
29
 
30
// State Space Processor Outputs
31
 
32
static unsigned char done[1];
33
static unsigned char instr_addr[1];
34
static unsigned char const_addr[1];
35
static unsigned char reg_0[2];
36
static unsigned char reg_1[2];
37
static unsigned char reg_2[2];
38
static unsigned char reg_3[2];
39
static unsigned char reg_4[2];
40
static unsigned char reg_5[2];
41
static unsigned char reg_6[2];
42
static unsigned char reg_7[2];
43
static unsigned char reg_8[2];
44
static unsigned char reg_9[2];
45
static unsigned char reg_a[2];
46
static unsigned char reg_b[2];
47
static unsigned char reg_c[2];
48
static unsigned char reg_d[2];
49
static unsigned char reg_e[2];
50
static unsigned char reg_f[2];
51
 
52
// External Constant Coefficient Memory
53
 
54
static unsigned int mem_const[256];
55
 
56
// External Instruction Memory
57
 
58
static unsigned int mem_instr[256];
59
 
60
// Constant Memory Initialization
61
 
62
void init_mem_const() {
63
  mem_const[0] = 0x00CD;      /* 0.8 ~= 0000000011001101 */
64
  mem_const[1] = 0x0034;      /* 0.2 ~= 0000000000110100 */
65
}
66
 
67
// Instruction Memory Initialization
68
 
69
void init_mem_instr() {
70
  /*
71
    Register Usage:
72
      Register 1 : Filter input.
73
      Register 2 : State and filter output.
74
      Register 3 : Multiplication constant operand.
75
      Register 4 : Multiplication accumulator.
76
 
77
    Algorithm:
78
      1. Multiply y(k-1) * 0.8
79
         1. Load 0.0 to Reg4
80
         2. Load 0.8 to Reg3
81
         3. Multiply (Repeated ShiftRight, AddCond, and ShiftLeft)
82
         4. Normalize (Repeated ShiftLeft)
83
         5. Limit Reg4 to Reg2
84
 
85
      2. Multiply x(k) * 0.2
86
         1. Load 0.0 to Reg4
87
         2. Load 0.2 to Reg3
88
         3. Multiply (Repeated ShiftRight, AddCond, and ShiftLeft)
89
         4. Normalize (Repeated ShiftLeft)
90
 
91
      3. Add (x(k)*0.2) + (y(k-1)*0.8)
92
         1. Add Reg4 and Reg2 to Reg2
93
         2. Limit Reg2 to Reg2
94
  */
95
 
96
  int i = 0;
97
 
98
  mem_instr[i++] = 0x0004;  // ShiftLeft  r0, r4      -- Load 0.0 to r4.
99
  mem_instr[i++] = 0x7003;  // Constant   #0, r3      -- Load 0.8 to r3.
100
 
101
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3      -- Shift lsb into Flag.
102
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4  -- Conditional add basic on Flag.
103
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2      -- Shift operand left and repeat...
104
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
105
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
106
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2
107
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
108
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
109
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2
110
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
111
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
112
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2
113
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
114
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
115
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2
116
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
117
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
118
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2
119
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
120
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
121
  mem_instr[i++] = 0x0202;  // ShiftLeft  r2, r2
122
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
123
  mem_instr[i++] = 0x4424;  // AddCond    r4, r2, r4
124
 
125
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4      -- Normalize the mulitplication result.
126
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
127
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
128
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
129
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
130
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
131
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
132
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
133
  mem_instr[i++] = 0x2402;  // Limit      r4, r2      -- Limit and move result to r2.
134
 
135
  mem_instr[i++] = 0x0004;  // ShiftLeft  r0, r4      -- Load 0.0 to r4.
136
  mem_instr[i++] = 0x7013;  // Constant   #1, r3      -- Load 0.2 to r3.
137
 
138
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3      -- Shift lsb into Flag.
139
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4  -- Conditional add basic on Flag.
140
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1      -- Shift operand left and repeat...
141
 
142
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
143
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
144
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1
145
 
146
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
147
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
148
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1
149
 
150
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
151
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
152
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1
153
 
154
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
155
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
156
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1
157
 
158
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
159
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
160
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1
161
 
162
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
163
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
164
  mem_instr[i++] = 0x0101;  // ShiftLeft  r1, r1
165
 
166
  mem_instr[i++] = 0x1303;  // ShiftRight r3, r3
167
  mem_instr[i++] = 0x4414;  // AddCond    r4, r1, r4
168
 
169
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4      -- Normalize the mulitplication result.
170
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
171
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
172
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
173
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
174
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
175
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
176
  mem_instr[i++] = 0x1404;  // ShiftRight r4, r4
177
  mem_instr[i++] = 0x3422;  // Add        r4, r2, r2  -- Add the 2 multiplication results.
178
  mem_instr[i++] = 0x2202;  // Limit      r2, r2      -- Limit the addition result.
179
 
180
  mem_instr[i++] = 0x8000;  // Halt                   -- Halt the cycle.
181
 
182
}
183
 
184
// Initialize simulation.
185
 
186
void sim_init() {
187
  // Init memories.
188
  init_mem_const();
189
  init_mem_instr();
190
 
191
  // Clear input data.
192
  reset[0] = 0;
193
  cycle[0] = 0;
194
  instr_data[1] = 0; instr_data[0] = 0;
195
  const_data[1] = 0; const_data[0] = 0;
196
  load_write[0] = 0;
197
  load_addr[0] = 0;
198
  load_data[1] = 0; load_data[0] = 0;
199
 
200
  // Bind ports.
201
  cf_ssp_16_8_ports(reset, cycle, instr_data, const_data, load_write, load_addr, load_data,
202
                    done, instr_addr, const_addr,
203
                    reg_0, reg_1, reg_2, reg_3, reg_4, reg_5, reg_6, reg_7,
204
                    reg_8, reg_9, reg_a, reg_b, reg_c, reg_d, reg_e, reg_f);
205
 
206
  // Init model and VCD recording.
207
  cf_ssp_16_8_sim_init("cf_ssp_16_8.vcd");
208
}
209
 
210
// End simulation.
211
 
212
void sim_end() {
213
  // End VCD recording.
214
  cf_ssp_16_8_sim_end();
215
}
216
 
217
// Cycle simulation.
218
 
219
void sim_cycle() {
220
  cf_ssp_16_8_calc();
221
  cf_ssp_16_8_sim_sample();
222
  cf_ssp_16_8_cycle_clock();
223
  // Fetch instruction from instruction memory.
224
  instr_data[0] = (unsigned char) (mem_instr[instr_addr[0]] & 0xFF);
225
  instr_data[1] = (unsigned char) (mem_instr[instr_addr[0]] >> 8 & 0xFF);
226
  // Fetch constant from constant memory.
227
  const_data[0] = (unsigned char) (mem_const[const_addr[0]] & 0xFF);
228
  const_data[1] = (unsigned char) (mem_const[const_addr[0]] >> 8 & 0xFF);
229
}
230
 
231
// Reset Processor
232
 
233
void processor_reset() {
234
  reset[0] = 1;
235
  sim_cycle();
236
  reset[0] = 0;
237
}
238
 
239
// Cycle Processor
240
 
241
void processor_cycle(int input) {
242
  int output;
243
 
244
  // Load input into register 1.
245
  load_write[0] = 1;
246
  load_addr[0] = 1;
247
  load_data[1] = input & 128 ? 0xFF : 0x00;
248
  load_data[0] = (unsigned char) (input & 0xFF);
249
  sim_cycle();
250
 
251
  // Signal processor to start cycle.
252
  load_write[0] = 0;
253
  cycle[0] = 1;
254
  sim_cycle();
255
  cycle[0] = 0;
256
  sim_cycle();
257
 
258
  // Cycle processor until done.
259
  while (!done[0]) sim_cycle();
260
 
261
  output = (int) reg_2[1] << 8 | (int) reg_2[0];
262
 
263
  printf("Input: %6d  Output: %6d\n", input, output);
264
}
265
 
266
 
267
int main(int argc, char *argv[]) {
268
  sim_init();
269
  processor_reset();
270
  processor_cycle(0);
271
  processor_cycle(0);
272
  processor_cycle(64);
273
  processor_cycle(64);
274
  processor_cycle(64);
275
  processor_cycle(64);
276
  processor_cycle(64);
277
  processor_cycle(64);
278
  processor_cycle(64);
279
  processor_cycle(64);
280
  processor_cycle(64);
281
  processor_cycle(64);
282
  processor_cycle(64);
283
  processor_cycle(64);
284
  sim_end();
285
  return 0;
286
}
287
 

powered by: WebSVN 2.1.0

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