HDLBits150~176(状态转移图-仿真结果-testbench)

接下来的练习记录

150 Exams/review2015 count1k

module top_module (
    input clk,
    input reset,
    output [9:0] q);
    
    parameter count = 999;
    
    always@(posedge clk) begin
        if(reset) begin
            q <= 10'b0;
        end
        else if(q == count)
            q <= 10'b0;
        else
            q <= q + 1;
    end

endmodule

151 Exams/review2015 shiftcount

module top_module (
    input clk,
    input shift_ena,
    input count_ena,
    input data,
    output [3:0] q);
    
    always@(posedge clk)begin
        if(shift_ena)begin
            q <= {q[2:0],data};
        end
        else if(count_ena)begin
            q <= q -1;
        end        
    end

endmodule

152 exams/review2015_fsmseq

  序列检测自动机
在这里插入图片描述

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output start_shifting);
    
	parameter RESET = 0,A =1,B =2,C=3,D=4;
    
    reg [4:0] state,next_state;
    always@(posedge clk) begin
        if(reset)
            state <= RESET;
        else
            state <= next_state;
    end
    
    always@(*) begin
        if(reset)
            next_state <= RESET;
        else begin
            case(state)
                RESET:next_state <= (data)?A:RESET;
                A:next_state <=(data)?B:RESET;
                B:next_state <=(data)?B:C;
                C:next_state <= (data)?D:RESET;
                D:next_state <= D;
            endcase
        end
    end
    assign start_shifting = (state == D);
    
        
endmodule

153 Exams/review2015 fsmshift

  这道题我使用两个标志位加计数器的方式完成,但第二种思路我觉得很好。可以借鉴一下。

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    
    reg [2:0] count;
    reg count_flag;
    reg reset_flag;
    
    always@(*) begin
        if(reset)
            count_flag <= 1'b0;
        else if(count == 3'b100)
            count_flag <= 1'b0;
        else if(count >= 0 && count < 3'b100)
            count_flag <= 1'b1;
        else
            count_flag <= 1'b0;
    end
    
    always@(posedge clk) begin
        if(reset)
            count <= 3'b00;
        else if(count == 3'b100)
            count <= 3'b111;
        else if(count_flag == 1'b1)
            count <= count + 1'b1;
    end
    
    always@(posedge clk) begin
        if(reset)
            reset_flag <= 1'b1;
        else
            reset_flag <= 1'b0;
    end
    
    assign shift_ena = count_flag  | reset_flag ;

endmodule

  另外一种思路

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    
    //记录时钟周期
    reg [2:0]cnt ;
    
    always @(posedge clk)
        begin
            if(reset)
                cnt <= 0;
            else if(cnt >= 4)
                cnt <= 4;
            else
                cnt = cnt + 1;
        end
    assign shift_ena = (cnt == 0 | cnt == 1 | cnt == 2 | cnt == 3);

endmodule


154 Exams/review2015 fsmshift

  本题的题意主体要完成的是序列监测,以及根据后面的信号输入进行后续的状态转移,我这里犯了一个错误就是S2在接收到1时的错误,看来做序列监测的时候还是不能大意,导致我仿真看了一下波形图,找到问题,下面依次是状态转移图,解答,仿真图,testbench。
在这里插入图片描述

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    input ack,
    input done_counting,
    output shift_ena,
    output counting,
    output done
    );
    
    parameter RESET = 8'b11111111 ,S1 = 8'b00000001 ,S2 = 8'b00000010,S3 = 8'b00000100,S4 = 8'b00001000,
    							   S5 = 8'b00010000 ,S6 = 8'b00100000,S7 = 8'b01000000,S8 = 8'b10000000;
    
    reg [7:0] state , next_state;
    reg [1:0] count;
    
    always@(posedge clk) begin
        if(reset)
            state <= RESET;
        else
            state <= next_state;
    end
    
    always@(posedge clk)begin
        if(reset)
            count <= 2'b00;
        else if(state == S4 && count != 2'b11)
            count <= count + 1'b1;
        else
            count <= 2'b00; 
    end
    
    always@(*) begin
        if(reset)
            next_state <= RESET;
        else begin
            case(state)
                RESET:next_state <= (!reset & data == 1'b1)?S1:RESET;
                S1:   next_state <= (data)?S2:RESET;
                S2:   next_state <= (data)?S2:S3;
                S3:   next_state <= (data)?S4:RESET;
                S4:	  next_state <= (count == 2'b11)?S5:S4;
                S5:   next_state <= (done_counting)?S6:S5;
                S6:   next_state <= (ack)?RESET:S6;
                default:next_state <= RESET;
            endcase  
        end
    end
    
    assign shift_ena = (state==  S4);
    assign counting = (state == S5);
    assign done = (state == S6);
    

endmodule

  仿真时序图
在这里插入图片描述

//testbench
module tb_top_module_154();
    reg  clk;
    reg  reset;      // Synchronous reset
    reg  data;
    reg  ack;
    reg  done_counting;
    wire shift_ena;
    wire counting;
    wire done;

    initial begin
        clk <= 1;
        reset <= 1'b0;
    end

    always begin
        #2 clk = ~clk;
    end

    initial begin
        #4
        data <= 1'b1;
        #2
        data <= 1'b0;
        #6
        data <= 1'b1;
        #2
        data <= 1'b0;
        #8
        data <= 1'b1;
        #4
        data <= 1'b0;
        #2
        data <= 1'b1;
        #4
        data <= 1'b0;
        #2
        data <= 1'b1;
        #8
        data <= 1'b0;
        #2
        data <= 1'b1;
        #14
        data <= 1'b0;
        #2
        data <= 1'b1;
        #4;
    end

    initial begin
        done_counting <= 1'b0;
        #48
        done_counting <= 1'b1;
        #2
        done_counting <= 1'b0;
        #14;
    end

    initial begin
        ack <= 1'b0;
        #6;
        ack <= 1'b1;
        #2
        ack <= 1'b0;
        #14
        ack <= 1'b1;
        #2
        ack <= 1'b0;
        #22
        ack <= 1'b1;
        #2
        ack <= 1'b0;
        #16;
    end

    top_module_154 tb_top_module_inst(
        .clk(clk),
        .reset(reset),
        .data(data),
        .ack(ack),
        .done_counting(done_counting),
        .shift_ena(shift_ena),
        .counting(counting),
        .done(done)
    );

    

endmodule

155 Exams/review2015 fsm

  155的状态转移图大体没有变动,需要改变的就是S5到S6的转变,然后其中在S4时要记录移位得到的数据count,然后我用round信号记录需要计数几轮,assign round <= count + 1’b1,这样更加好判断。
  还需要注意的点是,在计数时,我刚开始想通过for循环来完成计数,但是我之前看过在verilog中要避免写for循环,所有通过 判断语句来写循环。

module top_module_155 (
    input clk,
    input reset,      // Synchronous reset
    input data,
    input ack,
    output [3:0] count,
    output counting,
    output done
   );
	
    parameter thousand = 1000;
    parameter RESET = 8'b11111111 ,S1 = 8'b00000001 ,S2 = 8'b00000010,S3 = 8'b00000100,S4 = 8'b00001000,
    							   S5 = 8'b00010000 ,S6 = 8'b00100000,S7 = 8'b01000000,S8 = 8'b10000000;
    
    reg [7:0] state , next_state;
    reg [1:0] num;
    reg [9:0] i;
    wire [3:0] round;


    assign round = count + 1'b1;
    always@(posedge clk) begin
        if(reset)
            state <= RESET;
        else
            state <= next_state;
    end
    
    always@(posedge clk)begin
        if(reset)
           	count <= 4'b0;
        else if(state == S4)
            count <= {count[2:0],data};
        else if(state == S5 && i == thousand -1'b1 && count != 0 )
            count <= count - 1'b1;
        else if(next_state == S6)
            count <= 4'b0;
        else
            count <= count;
    end
   
    
    always@(posedge clk)begin
        if(reset)
            num <= 2'b00;
        else if(state == S4 && num != 2'b11)
            num <= num + 1'b1;
        else
            num <= 2'b00; 
    end
    
    always@(posedge clk)begin
        if(reset) begin
            i <= 10'b0;
        end
        else if(state == S5) begin
            if(i == thousand -1'b1) begin
                i <= 10'b0;
            end
            else begin
                i <= i +1'b1;
            end
        end
    end
            
    
    always@(*) begin
        if(reset)
            next_state <= RESET;
        else begin
            case(state)
                RESET:next_state <= (!reset & data == 1'b1)?S1:RESET;
                S1:   next_state <= (data)?S2:RESET;
                S2:   next_state <= (data)?S2:S3;
                S3:   next_state <= (data)?S4:RESET;
                S4:	  next_state <= (num == 2'b11)?S5:S4;
                S5:   next_state <= (i == thousand -1'b1 && round == 1'b1)?S6:S5;
                S6:   next_state <= (ack)?RESET:S6;
                default:next_state <= RESET;
            endcase  
        end
    end
    
    assign counting = (state == S5);
    assign done = (state == S6);
endmodule

  前几个状态的仿真图
在这里插入图片描述
  155的testbench

module tb_top_module_155();
    reg  clk;
    reg  reset;      // Synchronous reset
    reg  data;
    reg  ack;
    wire  [3:0] count;
    wire counting;
    wire done;

    initial begin
        clk <= 1;
        reset <= 1'b1;
        #4;
        reset <= 1'b0;
    end

    always begin
        #2 clk = ~clk;
    end

    initial begin
        data <= 1'b0;
        #4
        data <= 1'b1;
        #4
        data <= 1'b0;
        #8
        data <= 1'b1;
        #8
        data <= 1'b0;
        #4
        data <= 1'b1;
        #4
        data <= 1'b0;
        #12
        data <= 1'b1;
        #4
        data <= 1'b0;
    end


    initial begin
        ack <= 1'b0;
        #6;
        ack <= 1'b1;
        #2
        ack <= 1'b0;
        #14
        ack <= 1'b1;
        #2
        ack <= 1'b0;
        #22
        ack <= 1'b1;
        #2
        ack <= 1'b0;
        #16;
    end

    top_module_155 tb_top_module_inst(
        .clk(clk),
        .reset(reset),
        .data(data),
        .ack(ack),
        .count(count),
        .counting(counting),
        .done(done)
    );

endmodule

156 Exams/review2015 fsmonehot

module top_module(
    input  d,
    input  done_counting,
    input  ack,
    input  [9:0] state,    // 10-bit one-hot current state
    output B3_next,
    output S_next,
    output S1_next,
    output Count_next,
    output Wait_next,
    output done,
    output counting,
    output shift_ena
); 
    //

    // You may use these parameters to access state bits using e.g., state[B2] instead of state[6].
    parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;

    
    assign B3_next = state[B2];
    assign S_next = (((state[S] || state[S1] ||state[S110]) && d == 1'b0 )|| state[Wait] && ack == 1'b1);
    assign S1_next = (state[S] && d == 1'b1);
    assign Count_next = state[B3] || (state[Count] && done_counting == 1'b0);
    assign Wait_next = (state[Wait] && ack == 1'b0) || (state[Count]&& done_counting == 1'b1);
    assign done = state[Wait];
    assign counting = state[Count];
    assign shift_ena = state[B0] ||state[B1] ||state[B2] ||state[B3];
    
endmodule

157-161 Finding bugs in code

//157
module top_module (
    input  sel,
    input  [7:0] a,
    input  [7:0] b,
    output [7:0] out  );   //修改这里

    assign out = sel?a:b ;  //使用这个逻辑更加好理解

endmodule

//158
module top_module (input a, input b, input c, output out);//
	reg outq;
    assign out = ~outq;
    andgate inst1 (
        .a(a),
        .b(b),
        .c(c),
        .d(1'b1),
        .e(1'b1),
        .out(outq)
    );

endmodule

//159
module top_module (
    input [1:0] sel,
    input [7:0] a,
    input [7:0] b,
    input [7:0] c,
    input [7:0] d,
    output [7:0] out  ); //

    wire [7:0] mux0,mux1;
    mux2 mux0_inst ( sel[0],    a,    b, mux0 );
    mux2 mux1_inst ( sel[0],    c,    d, mux1 );
    mux2 mux2_inst ( sel[1], mux0, mux1,  out );

endmodule

/160
// synthesis verilog_input_version verilog_2001
module top_module ( 
    input do_sub,
    input [7:0] a,
    input [7:0] b,
    output reg [7:0] out,
    output result_is_zero
);
	
    always @(*) begin
        case (do_sub)
          0: out = a+b;
          1: out = a-b;
        endcase
    end   
    
    assign result_is_zero = (out == 8'b0)?1:0;
endmodule
//161
module top_module (
    input [7:0] code,
    output reg [3:0] out,
    output reg valid=1 );//

    always @(*) begin
        case (code)
            8'h45: begin
                out = 0;
                valid <= 1'b1;
            end
            8'h16: begin
                out = 1;
                valid <= 1'b1;
            end 
            8'h1e: begin
                out = 2;
                valid <= 1'b1;
            end
            8'h26: begin
                out = 3;  //修改
                valid <= 1'b1;
            end
            8'h25: begin
                out = 4;
                valid <= 1'b1;
            end
            8'h2e: begin
                out = 5;
                valid <= 1'b1;
            end
            8'h36: begin
                out = 6;
                valid <= 1'b1;
            end
            8'h3d: begin
                out = 7;
                valid <= 1'b1;
            end
            8'h3e: begin
                out = 8;
                valid <= 1'b1;
            end  
            8'h46: begin
                out = 9;  //修改
                valid <= 1'b1;
            end  
            default: begin
                out <= 0;
                valid <= 0;
            end
        endcase
    end

endmodule


162- 171 Sim/circuit1

//162
module top_module (
    input a,
    input b,
    output q );//

    assign q = a&b; // Fix me
endmodule

//163
//同或 也就是 异或非
    assign q = !(a^b^c^d); // Fix me
//164
//卡诺图如下图所示:
    assign q = (a|b)&(c|d); // Fix me
//165
   assign q = b|c; // Fix me
//166
   module top_module (
    input [3:0] a,
    input [3:0] b,
    input [3:0] c,
    input [3:0] d,
    input [3:0] e,
    output [3:0] q );
    
    always@(*) begin
        if(c >= 4'b0 && c <= 4'b0011) begin
            case(c)
                4'b0000: q <= b;
                4'b0001: q <= e;
                4'b0010: q <= a;
                4'b0011: q <= d;
                default: q <= 4'b1111; 
            endcase
        end
        else
            q <= 4'b1111;
    end

endmodule
//167
module top_module (
    input [2:0] a,
    output [15:0] q ); 
    always@(*)begin
        case(a)
            3'b000:q <= 16'h1232;
            3'b001:q <= 16'haee0;
            3'b010:q <= 16'h27d4;
            3'b011:q <= 16'h5a0e;
            3'b100:q <= 16'h2066;
            3'b101:q <= 16'h64ce;
            4'b110:q <= 16'hc526;
            4'b111:q <= 16'h2f19;
            default:q <= 16'h0000;
        endcase
    end

endmodule
//168
module top_module (
    input clk,
    input a,
    output q );
    always@(posedge clk) begin
        q <= !a;
    end

endmodule
//169
module top_module (
    input clock,
    input a,
    output p,
    output q );
    
    always@(*)begin
        if(clock)
            p <= a;
        else
            p <= p;
    end
    
    always@(negedge clock)begin
        q <= a;
    end
endmodule
//170
//a是复位信号
module top_module (
    input clk,
    input a,
    output [3:0] q);
    
    always@(posedge clk)begin
        if(a)
            q <= 4'b0100;
        else begin
            if(q == 4'b0110)
                q <= 4'b0;
        	else
                q <= q + 1'b1;
        end
    end
endmodule

//171
module top_module (
    input clk,
    input a,
    input b,
    output q,
    output state  );
    reg next_state;
    parameter A=1'b0,B=1'b1;
    always @(*)begin
        case(state)
        	A:next_state = a&b?B:A;
            B:next_state = ((a|b)==1'b0)?A:B;
        endcase
    end
    always @ (posedge clk) begin
        state <= next_state;
    end
    
    assign q = ((state == A)&(a^b))|((state == B)& (~(a^b)));
endmodule


在这里插入图片描述

Testbench

172-176

//172
`timescale 1ps / 1ps
module top_module ( );
    reg clk;
    
    dut inst_dut(
        .clk	(clk)
    );
    
    initial begin
        clk = 1'b0;
    end
    
    always begin
        #5
        clk = ~clk;
    end

endmodule
//173
module top_module ( output reg A, output reg B );//
    initial begin
        A <= 1'b0;
        #10
        A <=1'b1;
        #10
        A <= 1'b0;
    end
    
    initial begin
        B <= 1'b0;
        #15
        B <=1'b1;
        #25
        B <= 1'b0;
    end

endmodule

//174
`timescale 1ps / 1ps
module top_module();
    reg [1:0] in;
    wire        out;
    
    andgate inst_andgate(
        .in(in),
        .out(out)
    );
    
    initial begin
        in = 2'b00;
        #10;
        in = 2'b01;
        #10;
        in = 2'b10;
        #10;
        in  = 2'b11;
    end
endmodule

//175
//testbench我喜欢分信号写
module top_module();
    reg clk;
    reg in;
    reg [2:0] s;
    wire out;
    
    q7 inst_q7(
        .clk(clk),
        .in(in),
        .s(s),
        .out(out)
    );
    
    
    
    initial begin
        clk = 1'b0;
    end
    
    always begin
        #5
        clk = ~clk;
    end
    
    initial begin
        in <= 1'b0;
        #20;
        in <= 1'b1;
        #10;
        in <= 1'b0;
        #10
        in <= 1'b1;
        #30;
        in <= 1'b0;
    end
        
    
    initial begin
        s <= 3'b010;
        #10;
        s <= 3'b110;
        #10
        s <= 3'b010;
        #10
        s <= 3'b111;
        #10
        s <= 3'b000;
    end
        

endmodule

//176
module top_module ();
    reg clk;
    reg reset;
    reg t;
    wire q;
    
    tff tff_inst(
        .clk(clk),
        .reset(reset),
        .t(t),
        .q(q)
    );
    
    initial begin
        clk = 1'b0;
    end
    always begin
        #5
        clk = ~clk;
    end
    
    initial begin
        reset <= 1'b0;
        t <= 1'b0;
        #10;
        reset <= 1'b1;
        #10;
        reset <= 1'b0;
        #10
        t <= 1'b1;     
    end
    

endmodule
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值