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

Subversion Repositories sudoku

[/] [sudoku/] [trunk/] [parameterized_rtl/] [piece.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 dsheffie
module piece(/*AUTOARG*/
2
   // Outputs
3
   changed, done, curr_value, error,
4
   // Inputs
5
   clk, rst, start, clr, start_value, my_row, my_col, my_square
6
   );
7
   parameter DIM_S = 9;
8
 
9
   input clk;
10
   input rst;
11
   input start;
12
   input clr;
13
 
14
   output changed;
15
   output done;
16
   output error;
17
 
18
   input [(DIM_S-1):0] start_value;
19
   output [(DIM_S-1):0] curr_value;
20
 
21
   input [(DIM_S*(DIM_S-1)-1):0] my_row;
22
   input [(DIM_S*(DIM_S-1)-1):0] my_col;
23
   input [(DIM_S*(DIM_S-1)-1):0] my_square;
24
 
25
   wire [(DIM_S-1):0]    row2d [(DIM_S-2):0];
26
   wire [(DIM_S-1):0]    col2d [(DIM_S-2):0];
27
   wire [(DIM_S-1):0]    sqr2d [(DIM_S-2):0];
28
 
29
   wire [(DIM_S-1):0]    row2d_solv [(DIM_S-2):0];
30
   wire [(DIM_S-1):0]    col2d_solv [(DIM_S-2):0];
31
   wire [(DIM_S-1):0]    sqr2d_solv [(DIM_S-2):0];
32
 
33
   reg [(DIM_S-1):0]     r_curr_value;
34
   reg [(DIM_S-1):0]     t_next_value;
35
   assign curr_value = r_curr_value;
36
 
37
   reg [2:0]     r_state, n_state;
38
   reg          r_solved, t_solved;
39
   reg          t_changed,r_changed;
40
   reg          t_error,r_error;
41
 
42
   assign done = r_solved;
43
   assign changed = r_changed;
44
   assign error = r_error;
45
 
46
   wire [(DIM_S-1):0]    w_solved;
47
 
48
   wire         w_piece_solved = (w_solved != 'd0);
49
   one_set #(.DIM_S(DIM_S))  s0 (r_curr_value, w_solved);
50
 
51
   always@(posedge clk)
52
     begin
53
        if(rst)
54
          begin
55
             r_curr_value <= 'd0;
56
             r_state <= 3'd0;
57
             r_solved <= 1'b0;
58
             r_changed <= 1'b0;
59
             r_error <= 1'b0;
60
          end
61
        else
62
          begin
63
             r_curr_value <= clr ? 'd0 : t_next_value;
64
             r_state <= clr ? 3'd0 : n_state;
65
             r_solved <= clr ? 1'b0 : t_solved;
66
             r_changed <= clr ? 1'b0 : t_changed;
67
             r_error <= clr ? 1'b0 : t_error;
68
          end
69
     end // always@ (posedge clk)
70
 
71
 
72
   genvar       i;
73
   generate
74
      for(i=0;i<(DIM_S-1);i=i+1)
75
        begin: unflatten
76
           assign row2d[i] = my_row[(DIM_S*(i+1))-1:DIM_S*i];
77
           assign col2d[i] = my_col[(DIM_S*(i+1))-1:DIM_S*i];
78
           assign sqr2d[i] = my_square[(DIM_S*(i+1))-1:DIM_S*i];
79
        end
80
   endgenerate
81
 
82
   generate
83
      for(i=0;i<(DIM_S-1);i=i+1)
84
        begin: unique_rows
85
           one_set #(.DIM_S(DIM_S)) rs (row2d[i], row2d_solv[i]);
86
           one_set #(.DIM_S(DIM_S)) cs (col2d[i], col2d_solv[i]);
87
           one_set #(.DIM_S(DIM_S)) ss (sqr2d[i], sqr2d_solv[i]);
88
        end
89
   endgenerate
90
 
91
   /* OR output of one_set to find cells
92
    * that are already set in col, grid, row */
93
   wire [(DIM_S-1):0] set_row, set_col, set_sqr;
94
   wire [(DIM_S-1):0] row_or, col_or, sqr_or;
95
 
96
   wire [(DIM_S-1):0] w_accum_row2d [(DIM_S-2):0];
97
   wire [(DIM_S-1):0] w_accum_col2d [(DIM_S-2):0];
98
   wire [(DIM_S-1):0] w_accum_sqr2d [(DIM_S-2):0];
99
 
100
   wire [(DIM_S-1):0] w_accum_row_or [(DIM_S-2):0];
101
   wire [(DIM_S-1):0] w_accum_col_or [(DIM_S-2):0];
102
   wire [(DIM_S-1):0] w_accum_sqr_or [(DIM_S-2):0];
103
 
104
   generate
105
      for(i=0;i<(DIM_S-1);i=i+1)
106
        begin: set_accums
107
           if(i==0)
108
             begin
109
                assign w_accum_row2d[i] = row2d_solv[i];
110
                assign w_accum_col2d[i] = col2d_solv[i];
111
                assign w_accum_sqr2d[i] = sqr2d_solv[i];
112
 
113
                assign w_accum_row_or[i] = row2d[i];
114
                assign w_accum_col_or[i] = col2d[i];
115
                assign w_accum_sqr_or[i] = sqr2d[i];
116
             end
117
           else
118
             begin
119
                assign w_accum_row2d[i] = w_accum_row2d[i-1] | row2d_solv[i];
120
                assign w_accum_col2d[i] = w_accum_col2d[i-1] | col2d_solv[i];
121
                assign w_accum_sqr2d[i] = w_accum_sqr2d[i-1] | sqr2d_solv[i];
122
 
123
                assign w_accum_row_or[i] = w_accum_row_or[i-1] | row2d[i];
124
                assign w_accum_col_or[i] = w_accum_col_or[i-1] | col2d[i];
125
                assign w_accum_sqr_or[i] = w_accum_sqr_or[i-1] | sqr2d[i];
126
             end
127
        end
128
   endgenerate
129
 
130
   assign set_row = w_accum_row2d[DIM_S-2];
131
   assign set_col = w_accum_col2d[DIM_S-2];
132
   assign set_sqr = w_accum_sqr2d[DIM_S-2];
133
 
134
   assign row_or = w_accum_row_or[DIM_S-2];
135
   assign col_or = w_accum_col_or[DIM_S-2];
136
   assign sqr_or = w_accum_sqr_or[DIM_S-2];
137
 
138
 
139
   integer ii;
140
   always@(posedge clk)
141
     begin
142
        if(rst==1'b0)
143
          begin
144
             for(ii=0;ii<(DIM_S-1);ii=ii+1)
145
               begin
146
                  if(row2d_solv[ii] === 'dx)
147
                    begin
148
                       $display("row %d", ii);
149
                       $stop();
150
                    end
151
               end
152
          end
153
     end
154
 
155
 
156
   wire [(DIM_S-1):0] row_nor = ~row_or;
157
   wire [(DIM_S-1):0] col_nor = ~col_or;
158
   wire [(DIM_S-1):0] sqr_nor = ~sqr_or;
159
 
160
   wire [(DIM_S-1):0] row_singleton;
161
   wire [(DIM_S-1):0] col_singleton;
162
   wire [(DIM_S-1):0] sqr_singleton;
163
 
164
   one_set #(.DIM_S(DIM_S)) s1 (r_curr_value & row_nor, row_singleton);
165
   one_set #(.DIM_S(DIM_S)) s2 (r_curr_value & col_nor, col_singleton);
166
   one_set #(.DIM_S(DIM_S)) s3 (r_curr_value & sqr_nor, sqr_singleton);
167
 
168
   /* these are the values of the set rows, columns, and
169
    * squares */
170
 
171
   wire [(DIM_S-1):0] not_poss = set_row | set_col | set_sqr;
172
   wire [(DIM_S-1):0] new_poss = r_curr_value & (~not_poss);
173
 
174
   wire               w_piece_zero = (r_curr_value == 'd0);
175
 
176
   always@(*)
177
     begin
178
        t_next_value = r_curr_value;
179
        n_state = r_state;
180
        t_solved = r_solved;
181
        t_changed = 1'b0;
182
        t_error = r_error;
183
 
184
        case(r_state)
185
          3'd0:
186
            begin
187
               if(start)
188
                 begin
189
                    t_next_value = start_value;
190
                    n_state = 3'd1;
191
                    t_changed = 1'b1;
192
                    t_error = 1'b0;
193
                 end
194
            end
195
          3'd1:
196
            begin
197
               if(w_piece_solved | w_piece_zero)
198
                 begin
199
                    t_solved = 1'b1;
200
                    n_state = 3'd7;
201
                    t_changed = 1'b1;
202
                    t_error = w_piece_zero;
203
                 end
204
               else
205
                 begin
206
                    t_changed = (new_poss != r_curr_value);
207
                    t_next_value = new_poss;
208
                    n_state = 3'd2;
209
                 end
210
            end // case: 3'd1
211
          3'd2:
212
            begin
213
               if(w_piece_solved | w_piece_zero)
214
                 begin
215
                    t_solved = 1'b1;
216
                    n_state = 3'd7;
217
                    t_error = w_piece_zero;
218
                 end
219
               else
220
                 begin
221
                    if(row_singleton != 'd0)
222
                      begin
223
                         //$display("used row singleton");
224
                         t_next_value = row_singleton;
225
                         t_changed = 1'b1;
226
                         t_solved = 1'b1;
227
                         n_state = 3'd7;
228
                      end
229
                    else if(col_singleton != 'd0)
230
                      begin
231
                         //$display("used col singleton");
232
                         t_next_value = col_singleton;
233
                         t_changed = 1'b1;
234
                         t_solved = 1'b1;
235
                         n_state = 3'd7;
236
                      end
237
                    else if(sqr_singleton != 'd0)
238
                      begin
239
                         //$display("used sqr singleton");
240
                         t_next_value = sqr_singleton;
241
                         t_changed = 1'b1;
242
                         t_solved = 1'b1;
243
                         n_state = 3'd7;
244
                      end
245
                    else
246
                      begin
247
                         n_state = 3'd1;
248
                      end
249
                 end
250
            end
251
          3'd7:
252
            begin
253
               t_solved = 1'b1;
254
               n_state = 3'd7;
255
            end
256
 
257
        endcase // case (r_state)
258
     end
259
endmodule // piece
260
 
261
module one_set(in, out);
262
   parameter DIM_S = 9;
263
   input [(DIM_S-1):0] in;
264
   output [(DIM_S-1):0] out;
265
 
266
   wire [(DIM_S-1):0]    w_ones = ~('d0);
267
   wire [(DIM_S-1):0]    w_m = in + w_ones;
268
   wire                 w_pow2 = ((w_m & in) == 'd0) && (in != 'd0);
269
 
270
   assign out = {DIM_S{w_pow2}} & in;
271
endmodule // one_set
272
 
273
module ones_count(in, out);
274
   parameter LG_IN_WIDTH = 4;
275
   localparam IN_WIDTH= (1 << LG_IN_WIDTH);
276
   localparam OUT_WIDTH = LG_IN_WIDTH;
277
 
278
   input [(IN_WIDTH-1):0] in;
279
   output [(OUT_WIDTH-1):0] out;
280
 
281
   localparam NUM_COUNT4 = IN_WIDTH/4;
282
   wire [2:0]                w_cnt4 [(NUM_COUNT4-1):0];
283
   wire [(OUT_WIDTH-1):0]   w_sum  [(NUM_COUNT4-1):0];
284
   genvar                   i;
285
 
286
   generate
287
      for(i=0;i<NUM_COUNT4;i=i+1)
288
        begin: count4z
289
           one_count4 cc (in[(4*(i+1))-1:4*(i)], w_cnt4[i]);
290
        end
291
   endgenerate
292
 
293
   generate
294
      for(i=0;i<NUM_COUNT4;i=i+1)
295
        begin: sumz
296
           if(i==0)
297
             begin
298
                assign w_sum[i] = { {(OUT_WIDTH-3){1'b0}}, w_cnt4[i]};
299
             end
300
           else
301
             begin
302
                assign w_sum[i] = w_sum[i-1] + { {(OUT_WIDTH-3){1'b0}}, w_cnt4[i]};
303
             end
304
        end
305
   endgenerate
306
 
307
   assign out = w_sum[NUM_COUNT4-1];
308
 
309
endmodule // ones_count
310
 
311
/*
312
module ones_count81(input [80:0] in, output [6:0] out);
313
   wire [83:0] w_in = {3'd0, in};
314
   wire [2:0]  ps [20:0];
315
 
316
   integer     x;
317
   reg [6:0]   t_sum;
318
   genvar      i;
319
   generate
320
      for(i=0;i<21;i=i+1)
321
        begin : builders
322
           one_count4 os (w_in[(4*(i+1)) - 1 : 4*i], ps[i]);
323
        end
324
   endgenerate
325
   always@(*)
326
                   begin
327
                      t_sum = 7'd0;
328
                      for(x = 0; x < 21; x=x+1)
329
                        begin
330
                           t_sum = t_sum + {3'd0, ps[x]};
331
                        end
332
                   end
333
   assign out = t_sum;
334
 
335
endmodule // ones_count81
336
*/
337
 
338
module one_count4(input [3:0] in, output [2:0] out);
339
   assign out =
340
                (in == 4'b0000) ? 3'd0 :
341
                (in == 4'b0001) ? 3'd1 :
342
                (in == 4'b0010) ? 3'd1 :
343
                (in == 4'b0011) ? 3'd2 :
344
                (in == 4'b0100) ? 3'd1 :
345
                (in == 4'b0101) ? 3'd2 :
346
                (in == 4'b0110) ? 3'd2 :
347
                (in == 4'b0111) ? 3'd3 :
348
                (in == 4'b1000) ? 3'd1 :
349
                (in == 4'b1001) ? 3'd2 :
350
                (in == 4'b1010) ? 3'd2 :
351
                (in == 4'b1011) ? 3'd3 :
352
                (in == 4'b1100) ? 3'd2 :
353
                (in == 4'b1101) ? 3'd3 :
354
                (in == 4'b1110) ? 3'd3 :
355
                3'd4;
356
endmodule // one_count4
357
 

powered by: WebSVN 2.1.0

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