当前位置:   article > 正文

Building large circuits_building large circuits 好难

building large circuits 好难

4bit shift register and down counter

module top_module (
    input clk,
    input shift_ena,
    input count_ena,
    input data,
    output [3:0] q);
    
    reg [3:0] cnt;
    always@(posedge clk)
        begin
            if(shift_ena)
                cnt <= {cnt[2:0],data};
            else if(count_ena)
                cnt <= cnt-1'b1;
            else 
                cnt <= cnt;
        end
    assign q = cnt;   
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

FSM sequence1101

隐含条件应该是不重叠。

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output start_shifting);
    
    parameter s0 = 3'd0, s1 = 3'd1, s2 = 3'd2;
    parameter s3 = 3'd3, s4 = 3'd4;
    
    reg [2:0] cs,ns;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else 
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = data ? s1 : s0;
                s1: ns = data ? s2 : s0;
                s2: ns = data ? s2 : s3;
                s3: ns = data ? s4 : s0;
                s4: ns = s4;
                default: ns = s0;
            endcase
        end
    assign start_shifting = cs==s4;
                

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

FSM enable shift register

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    
 	parameter s0 = 3'd0, s1 = 3'd1, s2 = 3'd2;
    parameter s3 = 3'd3, s4 = 3'd4;
    
    reg [2:0] cs,ns;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else 
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = s1;
                s1: ns = s2;
                s2: ns = s3;
                s3: ns = s4;
                s4: ns = s4;
                default: ns = s0;
            endcase
        end
    assign shift_ena = cs==s4 ? 1'b0 : 1'b1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

复位信号有效,进入状态s0,复位撤销,进入s1,持续到s3, 4个时钟周期为1,之后为0.

下一种方法:计数器

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    
    reg [1:0] cnt;
    wire a,b;
    assign a = shift_ena;        //开始计数
    assign b = a && cnt==2'd3;   //计满四个周期,停止计数。
    
    always@(posedge clk)
        begin
            if(reset)
                cnt <= 2'd0;
            else 
                cnt <= a ? (b ? 2'd0 : cnt+1'b1) : 2'd0;
        end
    always@(posedge clk)
        begin
            if(reset)
                shift_ena <= 1'b1;
            else if(b)
                shift_ena <= 1'b0;
        end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

the complete fsm

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output shift_ena,
    output counting,
    input done_counting,
    output done,
    input ack );
    
    parameter s0 = 4'd0, s1 = 4'd1, s2 = 4'd2;
    parameter s3 = 4'd3, s4 = 4'd4;   //1101
    parameter s5 = 4'd5, s6 = 4'd6, s7 = 4'd7; //移位4个时钟
    parameter cnt = 4'd8, WAIT = 4'd9; //计数和等待
    
    
    reg [3:0] cs,ns;
   
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = data ? s1 : s0;
                s1: ns = data ? s2 : s0;
                s2: ns = data ? s2 : s3;
                s3: ns = data ? s4 : s0;
                s4: ns = s5;
                s5: ns = s6;
                s6: ns = s7;
                s7: ns = cnt;
                cnt: ns = done_counting ? WAIT : cnt;
                WAIT: ns = ack ? s0 : WAIT;
                default: ns = s0;
            endcase
        end
    assign shift_ena = cs==s4 || cs==s5 || cs==s6 || cs==s7;
    assign counting = cs==cnt;
    assign done = cs==WAIT;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

the complete timer

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );

    
    parameter s0 = 4'd0, s1 = 4'd1, s2 = 4'd2;
    parameter s3 = 4'd3, s4 = 4'd4;   //1101
    parameter s5 = 4'd5, s6 = 4'd6, s7 = 4'd7; //移位4个时钟
    parameter cnt = 4'd8, WAIT = 4'd9; //计数和等待
    
    reg [3:0] cs,ns;
    reg [3:0] in;
    reg [15:0] counter;
    always@(posedge clk)
        begin
            if(reset)
                counter <= 16'd0;
            else if(ns==WAIT)
                counter <= 16'd0;
            else if(ns==cnt)
                counter <= counter + 1'b1;
        end
    
    reg [3:0] delay;
    always@(*)
        begin
            if(counter<=1000)
                delay = 4'd0;
            else if(counter>1000 && counter<=2000)
                delay = 4'd1;
            else if(counter>2000 && counter<=3000)
                delay = 4'd2;
            else if(counter>3000 && counter<=4000)
                delay = 4'd3;
            else if(counter>4000 && counter<=5000)
                delay = 4'd4;
            else if(counter>5000 && counter<=6000)
                delay = 4'd5;
            else if(counter>6000 && counter<=7000)
                delay = 4'd6;
            else if(counter>7000 && counter<=8000)
                delay = 4'd7;
            else if(counter>8000 && counter<=9000)
                delay = 4'd8;
            else if(counter>9000 && counter<=10000)
                delay = 4'd9;
            else if(counter>10000 && counter<=11000)
                delay = 4'd10;
            else if(counter>11000 && counter<=12000)
                delay = 4'd11;
            else if(counter>12000 && counter<=13000)
                delay = 4'd12;
            else if(counter>13000 && counter<=14000)
                delay = 4'd13;
            else if(counter>14000 && counter<=15000)
                delay = 4'd14;
            else 
                delay = 4'd15;
        end
    wire exact_sum;
    assign exact_sum = (counter==(in + 1)*1000) ? 1'b1 : 1'b0;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = data ? s1 : s0;
                s1: ns = data ? s2 : s0;
                s2: ns = data ? s2 : s3;
                s3: ns = data ? s4 : s0;
                s4: begin  ns = s5; in[3] = data; end
                s5: begin  ns = s6; in[2] = data; end
                s6: begin  ns = s7; in[1] = data; end
                s7: begin  ns = cnt;in[0] = data; end
                cnt: ns = exact_sum ? WAIT : cnt;
                WAIT: ns = ack ? s0 : WAIT;
                default: ns = s0;
            endcase
        end
    assign count = cs==cnt ? (in-delay) : 4'd0;
    assign counting = cs==cnt;
    assign done = cs==WAIT;


endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

最后一个独热码,就按照状态转移图写就行了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/648800
推荐阅读
相关标签
  

闽ICP备14008679号