/* MAX2top2001.v -------- ロジック回路実験ボード・トップ・モジュール HDL-CQ1 ボード製造テスト用トップ・モジュール 使用方法とテスト項目  クロック選択機能  単にリセット・スイッチを押すと,   水晶発振器をクロック源とするテスト開始  マニュアル・クロック・スイッチを押しながらリセットを押すと,   555をクロック源とするテスト開始    リセット後,マニュアル・クロック・スイッチを押す毎にテスト項目が推移する  テスト1:発振器 → 単体LED        (点滅) テスト2:スライド・スイッチ → 単体LED  (ビット対応で発光) テスト3:単体LED             (1ビットづつ点灯) テスト4:7セグメントLED         (1セグメントづつ点灯) テスト5:ワンショットマルチ → 単体LED  (パルス幅でLEDが変化)       右コントローラ → LED[3:0]       左コントローラ → LED[7:4] テスト6:スピーカー           (1KHz/100Hz連続音) テスト7:VGA出力             (ストライプ・パターン) Ver. 1.0 (2007.01.19) designed by Shinya KIMURA ------------------------------------- トランジスタ技術連載 BASICS (Digital) */ `default_nettype none `define OSC 3'b000 `define SLD_SW 3'b001 `define SNGL_LED 3'b010 `define SEG_LED 3'b011 `define ONE_SHOT 3'b100 `define SPKR 3'b101 `define VGA 3'b110 `define TEST_END 3'b111 module MAX2top( input wire XTAL, // X'tal OSC clock input wire MANCLK, // manual clock input wire DCLK, // 7-seg LED dynamic light on clock input wire RESET_N, // reset (active low) input wire [7:0] SLDSW, // slide switch input wire [1:0] RKT_PLS, // racket position pulse output wire [7:0] LED_N, // LED output wire [7:0] SEG_N, // 7-segment LED // [7:0] = {dot,g,f,e,d,c,b,a} output wire [3:0] SEGSEL_N, // 7-segment LED select // [3:0] = {left, .. , right} output wire RD, // VGA red output wire GR, // VGA green output wire BL, // VGA blue output wire H_SYNC_N, // horizontal sync. output wire V_SYNC_N, // vertical sync. output wire [1:0] RKT_TRG, // racket pulse trigger output wire SPKR); // speaker // internal signal (active high) wire [7:0] led; wire [7:0] seg; wire [3:0] segsel; wire [1:0] rkt_trg; wire H_sync; wire V_sync; wire rd, gr, bl; wire spkr; // active level conversion to positive logic assign LED_N = ~led; assign SEG_N = ~seg; assign SEGSEL_N = ~segsel; assign H_SYNC_N = ~H_sync; assign V_SYNC_N = ~V_sync; assign RD = rd; assign GR = gr; assign BL = bl; assign RKT_TRG = rkt_trg; assign SPKR = spkr; // additional internal signals reg clk_src; reg manclkd, manclkdd; reg clk2Hz; reg [2:0] mode; reg [7:0] ring_cntr8; reg [3:0] ring_cntr4; reg [3:0] segsel_test; reg [3:0] l_width, r_width; reg [3:0] width_count; reg [1:0] rkt_pls_d, rkt_pls_dd; wire go_next_mode; wire xtal1MHz, xtal100KHz, xtal10KHz, xtal1KHz, xtal100Hz, xtal4Hz, xtal1Hz, rc100Hz, rc4Hz, rc1Hz; wire clk1KHz, clk100Hz, clk4Hz, clk1Hz; wire l_one_shot_end, r_one_shot_end; wire [9:0] x_count; wire [9:0] y_count; wire x_disp; wire y_disp; // clock and clock source selection always @(negedge RESET_N) begin clk_src <= MANCLK; end assign clk1KHz = clk_src ? xtal1KHz : DCLK; assign clk100Hz = clk_src ? xtal100Hz : rc100Hz; assign clk4Hz = clk_src ? xtal4Hz : rc4Hz; div25 U0(XTAL, xtal1MHz ); div10 U1(xtal1MHz, xtal100KHz); div10 U2(xtal100KHz, xtal10KHz ); div10 U3(xtal10KHz, xtal1KHz ); div10 U4(xtal1KHz, xtal100Hz ); div25 U5(xtal100Hz, xtal4Hz ); div10 U7(DCLK, rc100Hz); div25 U8(rc100Hz, rc4Hz); always @(posedge clk4Hz) begin clk2Hz <= ~clk2Hz; end // test mode control always @(posedge clk100Hz, negedge RESET_N) begin if(!RESET_N) begin mode <= `OSC; end else if(go_next_mode) begin case (mode) `OSC : mode <= `SLD_SW; `SLD_SW : mode <= `SNGL_LED; `SNGL_LED: mode <= `SEG_LED; `SEG_LED : mode <= `ONE_SHOT; `ONE_SHOT: mode <= `SPKR; `SPKR : mode <= `VGA; `VGA : mode <= `TEST_END; `TEST_END: mode <= `TEST_END; default : mode <= `TEST_END; endcase end end // mode tarnsition trigger always @(posedge clk100Hz) begin manclkd <= MANCLK; manclkdd <= manclkd; end assign go_next_mode = ~manclkd & manclkdd; // 8-bit free run ring counter for LED and 7seg LED test always @(posedge clk4Hz, negedge RESET_N) begin if(!RESET_N) begin ring_cntr8 <= 8'h01; end else begin ring_cntr8 <= {ring_cntr8[6:0], ring_cntr8[7]}; end end // single LED connection assign led = (mode==`OSC ) ? (clk2Hz ? 8'hAA : 8'h55) : (mode==`SLD_SW ) ? SLDSW : (mode==`SNGL_LED) ? ring_cntr8 : (mode==`ONE_SHOT) ? {l_width, r_width} : 8'h00; // 7-segmet LED test always @(posedge clk4Hz, negedge RESET_N) begin if(!RESET_N) begin segsel_test <= 4'b0001; end else if(ring_cntr8==8'h80) begin segsel_test <= {segsel_test[2:0], segsel_test[3]}; end end // 7-segment LED dynamic right on for message display always @(posedge clk1KHz) begin if(!RESET_N) begin ring_cntr4 <= 4'h0; end else if(mode!=`SEG_LED) begin if(ring_cntr4==4'h0) begin ring_cntr4 <= 4'h1; end else begin ring_cntr4 <= {ring_cntr4[2:0], ring_cntr4[3]}; end end else begin ring_cntr4 <= 4'h0; end end assign segsel = (mode==`SEG_LED) ? segsel_test : ring_cntr4; // message display (and 7seg LED test) assign seg = (mode==`OSC ) ? (segsel==4'b0001 ? 8'b00111001 : // C segsel==4'b0010 ? 8'b01101101 : // S segsel==4'b0100 ? 8'b00111111 : // O segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): (mode==`SLD_SW ) ? (segsel==4'b0001 ? 8'b00011110 : // W segsel==4'b0010 ? 8'b00111100 : // W segsel==4'b0100 ? 8'b01101101 : // S segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): (mode==`SNGL_LED) ? (segsel==4'b0001 ? 8'b01011110 : // d segsel==4'b0010 ? 8'b01111011 : // e segsel==4'b0100 ? 8'b00111000 : // L segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): (mode==`SEG_LED ) ? ring_cntr8 : (mode==`ONE_SHOT) ? (segsel==4'b0001 ? 8'b01111011 : // e segsel==4'b0010 ? 8'b01010100 : // n segsel==4'b0100 ? 8'b00111111 : // O segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): (mode==`SPKR ) ? (segsel==4'b0001 ? 8'b01111000 : // k segsel==4'b0010 ? 8'b01110011 : // P segsel==4'b0100 ? 8'b01101101 : // S segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): (mode==`VGA ) ? (segsel==4'b0001 ? 8'b01110111 : // A segsel==4'b0010 ? 8'b00111101 : // G segsel==4'b0100 ? 8'b00111110 : // V segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): (mode==`TEST_END) ? (segsel==4'b0001 ? 8'b01011110 : // d segsel==4'b0010 ? 8'b01010100 : // n segsel==4'b0100 ? 8'b01111001 : // E segsel==4'b1000 ? 8'b00000000 : 8'b00000000 ): 8'b00000000; // one-shot test always @(posedge clk1KHz) begin if(clk4Hz) begin width_count <= 4'b000000; end else begin width_count <= width_count + 1'b1; end end always @(posedge clk1KHz) begin if(r_one_shot_end) begin r_width <= width_count; end if(l_one_shot_end) begin l_width <= width_count; end end assign rkt_trg = {clk4Hz, clk4Hz}; always @(posedge clk1KHz) begin rkt_pls_d <= RKT_PLS; rkt_pls_dd <= rkt_pls_d; end assign r_one_shot_end = ~rkt_pls_d[1] & rkt_pls_dd[1]; assign l_one_shot_end = ~rkt_pls_d[0] & rkt_pls_dd[0]; // speaker test assign spkr = (mode==`SPKR) & (clk2Hz ? clk1KHz : clk100Hz); // NTSC video sync. signal module syncgen syncgen(XTAL, // 25MHz RESET_N, H_sync, V_sync, x_count, y_count, x_disp, y_disp); assign rd = (mode==`VGA) & x_count[4] & x_disp & y_disp; assign gr = (mode==`VGA) & x_count[5] & x_disp & y_disp; assign bl = (mode==`VGA) & x_count[6] & x_disp & y_disp; endmodule module div10( input wire src, output wire dived); reg [3:0] counter; always @(posedge src) begin if(counter==4'b1001) begin counter <= 4'b0000; end else begin counter <= counter + 1'b1; end end assign dived = counter[3]; endmodule module div25( input wire src, output wire dived); reg [4:0] counter; always @(posedge src) begin if(counter==5'b11001) begin counter <= 5'b0000; end else begin counter <= counter + 1'b1; end end assign dived = counter[4]; endmodule