2014年6月15日 星期日

設計一個可以設定上數/下數計數值 的16位元計數器上數/下數電路--適用於DE2-70

設計一個可以設定上數/下數計數值 的16位元計數器上數/下數電路



Load ==>SW[17] with SW[15:0] Data 
Upper limit ==> KEY[1] with SW[15:0] Upper limit Data
Lower limit ==> KEY[2] with SW[15:0] Lower limit Data
reset ==> Reset


module updown_16bitcounter(
  input CLOCK_50,     //    50 MHz clock
  input [3:0] KEY,      //    Pushbutton[3:0]
  input [17:0] SW,     //    Toggle Switch[17:0]
  output [6:0]    HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7,  // Seven Segment Digits
  output [8:0] LEDG,   //    LED Green
  output [17:0] LEDR,   //    LED Red
  inout [35:0] GPIO_0,GPIO_1,    //    GPIO Connections
//    LCD Module 16X2
  output LCD_ON,     // LCD Power ON/OFF
  output LCD_BLON,     // LCD Back Light ON/OFF
  output LCD_RW,     // LCD Read/Write Select, 0 = Write, 1 = Read
  output LCD_EN,     // LCD Enable
  output LCD_RS,     // LCD Command/Data Select, 0 = Command, 1 = Data
  inout [7:0] LCD_DATA, // LCD Data bus 8 bits
  input  UART_RXD, //RS232 RXD
  output UART_TXD //RS232 TXD
);

//    All inout port turn to tri-state
assign    GPIO_0        =    36'hzzzzzzzzz;
assign    GPIO_1        =    36'hzzzzzzzzz;

//assign HEX0=7'b111_1111;  //off 7-segment Display
//assign HEX1=7'b111_1111;
//assign HEX2=7'b111_1111;
//assign HEX3=7'b111_1111;
//assign HEX4=7'b111_1111;
assign HEX5=7'b111_1111;
assign HEX6=7'b111_1111;
assign HEX7=7'b111_1111;

// Send switches to red leds 
assign LEDR = SW;

// turn LCD ON
assign    LCD_ON      =    1'b1;
assign    LCD_BLON    =    1'b1;

wire [15:0] upper_lim,lower_lim,count;
wire [3:0]ONES,TENS,HUNDREDS,THOUSAND,TEN_THOU;
wire clk_out;

clk_div_2hz(CLOCK_50 ,KEY[0], clk_out);

//upper_lower_limit(clk,lim_up,lim_lo,data,upper_lim,lower_lim);
upper_lower_limit u11(clk_out,KEY[1],KEY[2],SW[15:0],upper_lim,lower_lim);

updown_16bitcount u12(KEY[0],clk_out,SW[15:0],SW[17],upper_lim, lower_lim, count);

binary_to_BCD u0(count,ONES,TENS,HUNDREDS,THOUSAND,TEN_THOU);

hex_7seg u1(ONES,HEX0);
hex_7seg u2(TENS,HEX1);
hex_7seg u3(HUNDREDS,HEX2);
hex_7seg u4(THOUSAND,HEX3);
hex_7seg u5(TEN_THOU,HEX4);
endmodule



module upper_lower_limit(clk,lim_up,lim_lo,data,upper_lim,lower_lim);
input clk;
input lim_up,lim_lo;
input  [15:0] data;
output reg [15:0] upper_lim;
output reg [15:0] lower_lim;

always@(posedge clk or negedge lim_up or negedge lim_lo )
begin
   if (!lim_up)
      upper_lim <= #1 data;
   
   if (!lim_lo)
      lower_lim <= #1 data;
end
   
endmodule



module updown_16bitcount(reset, clk, data, load,
    upper_lim, lower_lim, count);
input reset, clk;
input [15:0] data;
input load;
input [15:0] upper_lim;
input [15:0] lower_lim;
output [15:0] count;
wire [15:0] count;

reg [15:0] cnt;
reg updown_ctl; // if updown_ctl==1'b0 : up counting
   // if updown_ctl==1'b1 : down counting
assign count = cnt;

always@(posedge clk or negedge reset)
begin
  if(!reset)
  begin
    cnt <= #1 16'h0;
    updown_ctl <= #1 1'b0;
  end
  else if (load==1'b1)
    begin
      cnt <= #1 data;
      if (data < upper_lim)
        updown_ctl <= #1 1'b0; // start to up count
      else
        updown_ctl <= #1 1'b1; // start to down count
    end
    else if (updown_ctl==1'b0) // up counting
           if (cnt == upper_lim)
           begin
             cnt <= #1 cnt - 16'h0001;
             updown_ctl <= #1 1'b1;
           end
           else
             cnt <= #1 cnt + 16'h0001;
         else               // down counting
           if (cnt == lower_lim)
           begin
             cnt <= #1 cnt + 16'h0001;
             updown_ctl <= #1 1'b0;
           end
           else
             cnt <= #1 cnt - 16'h0001;
end

endmodule


module binary_to_BCD(A,ONES,TENS,HUNDREDS,THOUSAND,TEN_THOU);
input [15:0] A;
output reg [3:0] ONES, TENS;
output reg [3:0] HUNDREDS,THOUSAND,TEN_THOU;

integer i;
always@(A)
begin 
        TEN_THOU=4'd0;
    THOUSAND=4'd0;
HUNDREDS=4'd0;
TENS=4'd0;
ONES=4'd0;
    
    for(i=15;i>=0;i=i-1)
    begin  
      //Add 3 to columns >=5
      if (TEN_THOU>=5)
          TEN_THOU=TEN_THOU+3;
      if (THOUSAND >=5)
        THOUSAND=THOUSAND+3;
      if (HUNDREDS >=5)
         HUNDREDS=HUNDREDS+3;
      if (TENS >=5)
        TENS=TENS+3;
      if (ONES >=5)
         ONES=ONES+3;
            
      //Shift left one
      TEN_THOU=TEN_THOU<<1;
      TEN_THOU[0]=THOUSAND[3];
      
      THOUSAND=THOUSAND<<1;
      THOUSAND[0]=HUNDREDS[3];
      
      HUNDREDS=HUNDREDS<<1;
      HUNDREDS[0]=TENS[3];
      
      TENS=TENS<<1;
      TENS[0]=ONES[3];
      
      ONES=ONES<<1;
      ONES[0]=A[i];
   
end
end

endmodule


module hex_7seg(hex_digit,seg);
input [3:0] hex_digit;
output [6:0] seg;
reg [6:0] seg;
// seg = {g,f,e,d,c,b,a};
// 0 is on and 1 is off

always @ (hex_digit)
case (hex_digit)
  4'h0: seg = 7'b1000000;
  4'h1: seg = 7'b1111001;  // ---a----
  4'h2: seg = 7'b0100100;  // |   |
  4'h3: seg = 7'b0110000;  // f   b
  4'h4: seg = 7'b0011001;  // |   |
  4'h5: seg = 7'b0010010;  // ---g----
  4'h6: seg = 7'b0000010;  // |   |
  4'h7: seg = 7'b1111000;  // e   c
  4'h8: seg = 7'b0000000;  // |   |
  4'h9: seg = 7'b0011000;  // ---d----
  4'ha: seg = 7'b0001000;
  4'hb: seg = 7'b0000011;
  4'hc: seg = 7'b1000110;
  4'hd: seg = 7'b0100001;
  4'he: seg = 7'b0000110;
  4'hf: seg = 7'b0001110;
endcase
endmodule


module clk_div_2hz(clk_in , Reset, clk_out);
input clk_in ;
input Reset;
output reg  clk_out;

integer i;
always@(posedge clk_in or negedge Reset) begin
 if (!Reset) begin
   i=0;
   clk_out=0;
   end
 else begin
    i= i+1 ;
    if (i>=12_499_999) begin
        clk_out  = ~clk_out;
        i=0;
       end
    end    
end            

endmodule

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...