/* permsums: Coded by Antti Karttunen, Jan 30-31 & Jun 21-... 2005. (Continued 27. February 2006.) Generate all permutations of the set {1..n} for successive n's 1, 2, 3, ..., 18, and collect the minimum and maximum of the sum p(1)*p(2) + p(2)*p(3) + p(3)*p(4) +... + p(n-1)*p(n) + p(n)*p(1). and show them on the 4x7-segment display. The meaning of the slide switches: SW_IN[1] (The second from the right) - if this is on (i.e. up) then pause after each permutation, and then, depending on SW_IN[0] (The rightmost slide switch) - if sw_in[0] is down, show the associated factorial expansion, its four most significant digits. - if sw_in[0] is up, show the associated permutation, its five lowermost digits. - otherwise, iterate over the set of all permutations of {1..n} (and show the associated f.ex or permutation of each, like above) and after that, pause, and depending on SW_IN[0] (The rightmost slide switch) - if sw_in[0] is down, show the minimum of the sums collected. - if sw_in[0] is up, show the maximum of the sums collected. The five rightmost leds will show the value nminus+1, i.e. the value of n whose permutations are currently iterated over as a binary expansion. Any time PB_IN2 (the leftmost push button) is pressed, the four-segment display will also show the same value. */ module permsums(CLK,PB_IN,SW_IN,SEG_OUT,DIGIT_OUT,LED_OUT); input CLK; input [2:0] PB_IN; input [2:0] SW_IN; output [7:0] SEG_OUT; output [3:0] DIGIT_OUT; output [7:0] LED_OUT; // n starts from 1, grows up to 18. reg [4:0] n = 1; // (1-18). reg [4:0] nplus1 = 2; // (2-19). // Registers for 17-digit factorial expansion // (from 00000000000000000 to HGFEDCBA987654321, where H=17, G=16, F=15, etc.) reg f1 = 0; // 0-1 reg [2:0] f2 = 0; // 0-2 reg [3:0] f3 = 0; // 0-3 reg [4:0] f4 = 0; // 0-4 reg [5:0] f5 = 0; // 0-5 reg [6:0] f6 = 0; // 0-6 reg [7:0] f7 = 0; // 0-7 reg [8:0] f8 = 0; // 0-8 reg [9:0] f9 = 0; // 0-9 reg [10:0] f10 = 0; // 0-10 reg [11:0] f11 = 0; // 0-11 reg [12:0] f12 = 0; // 0-12 reg [13:0] f13 = 0; // 0-13 reg [14:0] f14 = 0; // 0-14 reg [15:0] f15 = 0; // 0-15 reg [16:0] f16 = 0; // 0-16 reg [17:0] f17 = 0; // 0-17 // Wires out of the factorial expansion incrementer: wire g1; wire [2:0] g2; wire [3:0] g3; wire [4:0] g4; wire [5:0] g5; wire [6:0] g6; wire [7:0] g7; wire [8:0] g8; wire [9:0] g9; wire [10:0] g10; wire [11:0] g11; wire [12:0] g12; wire [13:0] g13; wire [14:0] g14; wire [15:0] g15; wire [16:0] g16; wire [17:0] g17; // Eighteen five-bit digits to hold a permutation of {1..18}. reg [4:0] p [17:0]; wire [4:0] wp [17:0]; // Same as wires. // The sum of such permutation computed in cyclical Quet-Deutsch manner. reg [13:0] psum = 0; wire [13:0] wpsum; /* So far commented out: wire [4:0] fexmsb1 = ((n < 5) ? {2'b00,f4} : (5 == n) ? {2'b00,f5} : (6 == n) ? {2'b00,f6} : (7 == n) ? {2'b00,f7} : (8 == n) ? {1'b0,f8} : (9 == n) ? {1'b0,f9} : (10 == n) ? {1'b0,f10} : (11 == n) ? {1'b0,f11} : (12 == n) ? {1'b0,f12} : (13 == n) ? {1'b0,f13} : (14 == n) ? {1'b0,f14} : (15 == n) ? {1'b0,f15} : (16 == n) ? f16 : f17); wire [4:0] fexmsb2 = ((n < 5) ? {3'b000,f3} : (5 == n) ? {2'b00,f4} : (6 == n) ? {2'b00,f5} : (7 == n) ? {2'b00,f6} : (8 == n) ? {2'b00,f7} : (9 == n) ? {1'b0,f8} : (10 == n) ? {1'b0,f9} : (11 == n) ? {1'b0,f10} : (12 == n) ? {1'b0,f11} : (13 == n) ? {1'b0,f12} : (14 == n) ? {1'b0,f13} : (15 == n) ? {1'b0,f14} : (16 == n) ? {1'b0,f15} : f16); wire [4:0] fexmsb3 = ((n < 5) ? {3'b000,f2} : (5 == n) ? {3'b000,f3} : (6 == n) ? {2'b00,f4} : (7 == n) ? {2'b00,f5} : (8 == n) ? {2'b00,f6} : (9 == n) ? {2'b00,f7} : (10 == n) ? {1'b0,f8} : (11 == n) ? {1'b0,f9} : (12 == n) ? {1'b0,f10} : (13 == n) ? {1'b0,f11} : (14 == n) ? {1'b0,f12} : (15 == n) ? {1'b0,f13} : (16 == n) ? {1'b0,f14} : {1'b0,f15}); wire [4:0] fexmsb4 = ((n < 5) ? {4'b0000,f1} : (5 == n) ? {3'b000,f2} : (6 == n) ? {3'b000,f3} : (7 == n) ? {2'b00,f4} : (8 == n) ? {2'b00,f5} : (9 == n) ? {2'b00,f6} : (10 == n) ? {2'b00,f7} : (11 == n) ? {1'b0,f8} : (12 == n) ? {1'b0,f9} : (13 == n) ? {1'b0,f10} : (14 == n) ? {1'b0,f11} : (15 == n) ? {1'b0,f12} : (16 == n) ? {1'b0,f13} : {1'b0,f14}); */ wire GND = 1'b0; wire CLK_HALVED; wire CLK_LOCKED; wire CLK0; puolita PUOLITAS(.CLKIN_IN(CLK), .RST_IN(GND), // Is this foolish, to leave RST floating? .CLKDV_OUT(CLK_HALVED), .CLKIN_IBUFG_OUT(), .CLK0_OUT(CLK0), .LOCKED_OUT(CLK_LOCKED)); shw5spec DIGDISPLAY(CLK_HALVED,p[3],p[2],p[1],p[0], /* (SW_IN[0] ? p[3] : fexmsb1), (SW_IN[0] ? p[2] : fexmsb2), (SW_IN[0] ? p[1] : fexmsb3), (SW_IN[0] ? p[0] : fexmsb4), */ 1'b1,1'b1,1'b1,1'b1, SEG_OUT,DIGIT_OUT); assign LED_OUT = (~SW_IN[0] ? {1,CLK_LOCKED,CLK_HALVED,n[4:0]} : psum[7:0]); inc17fex INCFEX(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10, f11,f12,f13,f14,f15,f16,f17, g1,g2,g3,g4,g5,g6,g7,g8,g9,g10, g11,g12,g13,g14,g15,g16,g17); fex17perm FEXPERM(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10, f11,f12,f13,f14,f15,f16,f17, wp[0],wp[1],wp[2],wp[3],wp[4],wp[5],wp[6],wp[7],wp[8],wp[9], wp[10],wp[11],wp[12],wp[13],wp[14],wp[15],wp[16],wp[17]); // The highest non-zero term is "extra", not included among the permuted digits. perm19sum PERMSUM(wpsum, p[0], (n > 1 ? p[1] : (1 == n ? nplus1 : 5'b00000)), (n > 2 ? p[2] : (2 == n ? nplus1 : 5'b00000)), (n > 3 ? p[3] : (3 == n ? nplus1 : 5'b00000)), (n > 4 ? p[4] : (4 == n ? nplus1 : 5'b00000)), (n > 5 ? p[5] : (5 == n ? nplus1 : 5'b00000)), (n > 6 ? p[6] : (6 == n ? nplus1 : 5'b00000)), (n > 7 ? p[7] : (7 == n ? nplus1 : 5'b00000)), (n > 8 ? p[8] : (8 == n ? nplus1 : 5'b00000)), (n > 9 ? p[9] : (9 == n ? nplus1 : 5'b00000)), (n > 10 ? p[10] : (10 == n ? nplus1 : 5'b00000)), (n > 11 ? p[11] : (11 == n ? nplus1 : 5'b00000)), (n > 12 ? p[12] : (12 == n ? nplus1 : 5'b00000)), (n > 13 ? p[13] : (13 == n ? nplus1 : 5'b00000)), (n > 14 ? p[14] : (14 == n ? nplus1 : 5'b00000)), (n > 15 ? p[15] : (15 == n ? nplus1 : 5'b00000)), (n > 16 ? p[16] : (16 == n ? nplus1 : 5'b00000)), (n > 17 ? p[17] : (17 == n ? nplus1 : 5'b00000)), ((18 == n) ? nplus1 : 5'b00000), ((18 == n) ? 5'b00000 : nplus1)); wire PB_IN0; // State of the debounced push button for incrementing. reg pb_in0_prev = 0; // is saved here also. debounced_button DBB0(CLK_HALVED,PB_IN[0],PB_IN0); wire inc_fex = (SW_IN[1] | (PB_IN0 && ~pb_in0_prev)); wire PB_IN1; // State of the debounced push button for incrementing. reg pb_in1_prev = 1; // is saved here also. debounced_button DBB1(CLK_HALVED,PB_IN[1],PB_IN1); wire inc_n = (PB_IN1 && ~pb_in1_prev); integer i; always @(posedge CLK_HALVED) begin pb_in0_prev <= PB_IN0; pb_in1_prev <= PB_IN1; f1 <= (inc_fex ? g1 : f1); f2 <= (inc_fex ? g2 : f2); f3 <= (inc_fex ? g3 : f3); f4 <= (inc_fex ? g4 : f4); f5 <= (inc_fex ? g5 : f5); f6 <= (inc_fex ? g6 : f6); f7 <= (inc_fex ? g7 : f7); f8 <= (inc_fex ? g8 : f8); f9 <= (inc_fex ? g9 : f9); f10 <= (inc_fex ? g10 : f10); f11 <= (inc_fex ? g11 : f11); f12 <= (inc_fex ? g12 : f12); f13 <= (inc_fex ? g13 : f13); f14 <= (inc_fex ? g14 : f14); f15 <= (inc_fex ? g15 : f15); f16 <= (inc_fex ? g16 : f16); f17 <= (inc_fex ? g17 : f17); n <= (inc_n ? nplus1 : n); nplus1 <= (inc_n ? nplus1+1 : nplus1); for(i=0; i<=17; i=i+1) p[i] <= wp[i]; psum <= wpsum; end endmodule