跳轉到

Counters

Four-bit binary counter

原題:Four-bit binary counter

重點是用always來計數。

Verilog
module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output reg[3:0] q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0000;
        else q<= q + 4'b0001;
    end
endmodule

Decade counter

原題:Decade counter

重點是用always來計數,只是數到9,多一個條件。

Verilog
module top_module (
    input clk,
    input reset,        // Synchronous active-high reset
    output reg[3:0] q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0000;
        else if(q == 4'b1001) q <= 4'b0000;
        else q<= q + 4'b0001;
    end
endmodule

Decade counter again

原題:Decade counter again

重點是用always來計數,只是變成從1數到10。

Verilog
module top_module (
    input clk,
    input reset,
    output reg[3:0] q);
    always@(posedge clk)begin
        if(reset) q <=4'b0001;
        else if(q == 4'b1010) q<=4'b0001;
        else q <= q + 4'b0001;
    end
endmodule

Slow decade counter

原題:Slow decade counter

和前一題類似,只是變成用另一個輸入計數。

Verilog
module top_module (
    input clk,
    input slowena,
    input reset,
    output reg[3:0] q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0000;
        else if(slowena)begin
            if(q == 4'b1001) q<= 4'b0000;
            else q <= q + 4'b0001;
        end
        else q <= q;
    end
endmodule

Counter 1-12

原題:Counter 1-12

題目給了完整的計數器,然後要求外接控制reset和數到12。

Verilog
module top_module (
    input clk,
    input reset,
    input enable,
    output [3:0] Q,
    output c_enable,
    output c_load,
    output [3:0] c_d
); //
    assign c_enable = enable;
    assign c_load = reset | (enable & (Q == 4'b1100));
    assign c_d = 4'b0001;
    count4 the_counter (clk, c_enable, c_load, c_d ,Q);
endmodule

Counter 1000

原題:Counter 1000

題目給了BCD counter,然後要連續接3個BCD counter數到1000。

Verilog
module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire [3:0] one, ten, hundred;
    wire is_ten, is_hundred;
    assign is_ten = (one == 4'b1001);
    assign is_hundred = is_ten & (ten == 4'b1001);
    assign c_enable = {is_hundred,is_ten,1'b1};
    assign OneHertz = is_hundred & (hundred == 4'b1001);
    bcdcount counter0 (clk, reset, c_enable[0], one);
    bcdcount counter1 (clk, reset, c_enable[1], ten);
    bcdcount counter2 (clk, reset, c_enable[2], hundred);
endmodule

4-digit decimal counter

原題:4-digit decimal counter

需要自己實作一個BCD,然後要將4個BCD相接,數到9999。

Verilog
module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    wire is_ten , is_hundred, is_thousand;
    assign is_ten = (q[3:0] == 4'b1001);
    assign is_hundred = (q[7:4] == 4'b1001) & is_ten;
    assign is_thousand = (q[11:8] == 4'b1001) & is_hundred & is_ten;
    assign ena = {is_thousand, is_hundred, is_ten};
    BCD BCD0(.clk(clk),.reset(reset),.enable( 1'b1 ),.q(q[3:0]));
    BCD BCD1(.clk(clk),.reset(reset),.enable(ena[1]),.q(q[7:4]));
    BCD BCD2(.clk(clk),.reset(reset),.enable(ena[2]),.q(q[11:8]));
    BCD BCD3(.clk(clk),.reset(reset),.enable(ena[3]),.q(q[15:12]));
endmodule

module BCD(
    input clk,
    input reset,
    input enable,
    output reg [4:0] q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0000;
        else if(enable)begin
            if(q == 4'b1001) q <= 4'b0000;
            else q <= q + 4'b0001;
        end
        else q <= q;
    end
endmodule

12-hour clock

原題:12-hour clock

實作一個時鐘,算是目前刷題第一次要寫很多程式。

Verilog
module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss);

    wire enas2,enam1,enam2,enah1,enah2,enapm,ld;
    BCD_zero_to_nine s1( .clk(clk), .reset(reset), .enable(ena), .q(ss[3:0]));

    assign enas2 = ena & (ss[3:0] == 4'b1001);
    BCD_zero_to_six s2( .clk(clk), .reset(reset), .enable(enas2), .q(ss[7:4]));

    assign enam1 = enas2 & (ss[7:4] == 4'b0101);
    BCD_zero_to_nine m1( .clk(clk), .reset(reset), .enable(enam1), .q(mm[3:0]));

    assign enam2 = enam1 & (mm[3:0] == 4'b1001);
    BCD_zero_to_six m2( .clk(clk), .reset(reset), .enable(enam2), .q(mm[7:4]));    

    assign enah1 = enam2 & (mm[7:4] == 4'b0101);
    assign ld = enah1 & (hh == 8'b0001_0010);    
    BCD_zero_to_nine_wload h1( .clk(clk), .reset(reset), .enable(enah1), .load(ld), .q(hh[3:0]));

    assign enah2 = (enah1 & (hh[3:0] == 4'b1001)) | ld;
    BCD_zero_to_one_wload h2( .clk(clk), .reset(reset), .enable(enah2), .load(ld), .q(hh[7:4]));

    assign enapm = enah1 & (hh == 8'b0001_0001);
    PM is_pm( .clk(clk), .reset(reset), .enable(enapm), .pm(pm));
endmodule

module BCD_zero_to_nine(
    input clk,
    input reset,
    input enable,
    output reg [3:0]q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0000;
        else if(enable)begin
            if(q == 4'b1001) q <= 4'b0000;
            else q <= q + 4'b0001;
        end
        else q <= q;
    end
endmodule

module BCD_zero_to_six(
    input clk,
    input reset,
    input enable,
    output reg [3:0]q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0000;
        else if(enable)begin
            if(q == 4'b0101) q <= 4'b0000;
            else q <= q + 4'b0001;
        end
        else q <= q;
    end
endmodule

module BCD_zero_to_nine_wload(
    input clk,
    input reset,
    input enable,
    input load,
    output reg [3:0]q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0010;
        else if(enable)begin
            if(load) q <= 4'b0001;
            else if(q == 4'b1001) q <= 4'b0000;
            else q <= q + 4'b0001;
        end
        else q <= q;
    end
endmodule

module BCD_zero_to_one_wload(
    input clk,
    input reset,
    input enable,
    input load,
    output reg [3:0]q);
    always@(posedge clk)begin
        if(reset) q <= 4'b0001;
        else if(enable)begin
            if(load) q <= 4'b0000;
            else q <= q + 4'b0001;
        end
        else q <= q;
    end
endmodule

module PM(
    input clk,
    input reset,
    input enable,
    output reg pm);
    always@(posedge clk)begin
        if(reset) pm <= 1'b0;
        else if(enable) pm <= pm ^ 1'b1;
        else pm <= pm;
    end
endmodule