verilog(二) HDLBits



Circuits

Combinational Logic

Multiplexers

4.14****************************

Mux256to1v
module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    assign out = in[sel*4+3 -: 4];

endmodule

不能写成 assign = out[sel*4+3 : sel*4],右限不能是变量
使用 -: ,+: 
-:      变量[结束地址 -: 数据位宽] <–等价于–> 变量[结束地址:(结束地址-数据位宽+1)]
+: 	变量[起始地址 +: 数据位宽] <–等价于–> 变量[(起始地址+数据位宽-1):起始地址]

Arithmetic Circuits

xxx adder

都可以用以下:

assign {cout,sum} = a+b+cin;
3-bit binary adder
module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    assign {cout[0],sum[0]} = a[0]+b[0]+cin;
    assign {cout[1],sum[1]} = a[1]+b[1]+cout[0];
    assign {cout[2],sum[2]} = a[2]+b[2]+cout[1];       
endmodule

Adder
module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    wire [2:0] cout;
    assign {cout[0],sum[0]} = x[0]+y[0];
    assign {cout[1],sum[1]} = x[1]+y[1]+cout[0];
    assign {cout[2],sum[2]} = x[2]+y[2]+cout[1];  
    assign {sum[4],sum[3]} = x[3]+y[3]+cout[2];
    
endmodule

Signed addition overflow
module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    wire [99:0] mid_cout;
    
    fulladder fulladder_0(a[0],b[0],cin,mid_cout[0],sum[0]);
    
    genvar i;
    generate 
        for(i=1;i<100;i++) begin:fulladder
            fulladder fulladder_i(a[i],b[i],mid_cout[i-1],mid_cout[i],sum[i]);
        end      
    endgenerate
    
    assign cout = mid_cout[99];

endmodule

module fulladder(a,b,cin,cout,sum);
    input a,b,cin;
    output cout,sum;
    assign {cout,sum} = a+b+cin;
    
endmodule

4-digit BCD adder
module top_module( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
    
    wire [3:0] mid_cout;
    
    bcd_fadd bcd_fadd_0(a[3:0],b[3:0],cin,mid_cout[0],sum[3:0]);
                                 
    assign cout = mid_cout[3];
    genvar i;
    generate
        for(i=1;i<4;i++)
            begin:bcd_fadd
                bcd_fadd bcd_fadd_i(a[4*i+3 -: 4],b[4*i+3 -: 4],mid_cout[i-1],mid_cout[i],sum[4*i+3 -: 4]);
            end           
    endgenerate
      
endmodule

Karnaugh Map to Circuit

3-variable
module top_module(
    input a,
    input b,
    input c,
    output out  ); 
    wire [2:0] mid;
    assign mid = {a,b,c};
    assign out = (mid==0)? 0:1;   	

endmodule
4-variable
module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    wire [3:0] mid;
    assign mid={a,b,c,d};
    always@(*)
        case(mid)
            4'b1100:out=0;
            4'b1101:out=0;
            4'b0011:out=0;
            4'b0101:out=0;
            4'b1110:out=0;
            4'b1010:out=0;
            default:out=1;
        endcase
            
endmodule

***********4.16

K-map implemented with a multiplexer
module top_module (
    input c,
    input d,
    output [3:0] mux_in
    
); 
    wire [1:0] cd;
    assign cd = {c,d};
    always@(*)
        begin
        case(cd)
            0:mux_in = 0100;
            1:mux_in = 0001;
            2:mux_in = 0101;
            3:mux_in = 1001;
            default:mux_in = 0100;
        endcase
        end

endmodule

Sequential Logic

Latches and Flip-Flops

DDF with byte enable
module top_module (
    input clk,
    input resetn,
    input [1:0] byteena,
    input [15:0] d,
    output [15:0] q
);
    always@(posedge clk)
        begin 
            if(resetn == 0)
                q<={8{1'b0}};
            else 
                begin
                if(byteena[1])
                    q[15:8]<= d[15:8];
            	if(byteena[0])
                    q[7:0]<= d[7:0];
                end
        end
           
endmodule
Mux and DFF
module top_module (
	input clk,
	input L,
	input r_in,
	input q_in,
	output reg Q);
    
    always@(posedge clk)
        begin
            case(L)
                0:Q <= q_in;
                1:Q <= r_in;
                default:Q <= 0;
            endcase
        end

endmodule

Mux and DFF
module top_module (
    input clk,
    input w, R, E, L,
    output Q
);
    always@(posedge clk)
        begin
            case(L)
                0:case(E)
                    0:Q <= Q;
                    1:Q <= w;
                    default:Q <= 0;
                endcase
                1:Q <= R;
                default:Q <= 0;
            endcase
        end
        

endmodule

*************4.17

DFFs and gates
module top_module (
    input clk,
    input x,
    output z
); 
    
    reg [2:0]	Q;
    always@(posedge clk)begin
        Q[0] <= Q[0] ^ x;
        Q[1] <= ~Q[1] & x;
        Q[2] <= ~Q[2] | x;
    end
    
    assign z = ~(| Q);
 
endmodule
Create circuit from truth table
module top_module (
    input clk,
    input j,
    input k,
    output Q);
    wire [1:0] jk;
    assign jk = {j,k};
    always@(posedge clk)
        begin
            case(jk)
                0:Q <= Q;
                1:Q <= 0;
                2:Q <= 1;
                3:Q <= ~Q;
                default:Q <= 0;
            endcase
        end

endmodule
Detect an edge
always 块结束后,统一赋值
module top_module (
    input clk,
    input [7:0] in,
    output [7:0] pedge    
);
    integer i;
    reg [7:0] in_tmp;
    always@(posedge clk)
        begin
        	in_tmp <= in;
            for(i=0;i<=7;i++)
                begin
                    if(in_tmp[i]==0 && in[i]==1)
                        pedge[i]=1;
                    else 
                        pedge[i]=0;
                end
        end
    
endmodule
Detect both edges
module top_module (
    input clk,
    input [7:0] in,
    output [7:0] anyedge
);

    integer i;
    reg [7:0] in_tmp;
    always@(posedge clk)
        begin
            in_tmp <= in;
            for(i=0;i<=7;i++)
                begin
                    if(in_tmp[i]^in[i])
                        anyedge[i]=1;
                    else
                        anyedge[i]=0;
                end
        end
    
endmodule

Edge capture register
module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output [31:0] out
);
    reg [31:0] in_last;//the input in the last clk
integer i;
    always@( posedge clk )
	begin
        in_last <= in;
		if(reset)
		out<={32{1'b0}};
		else
			begin

				for(i=0;i<=31;i++)
					begin
                        if(in_last[i]==1 && in[i]==0) 
                        //下降沿out <= out |(in_last & ~in);
							out[i] <= 1;   

					end
			end
	end
endmodule

Dual-edge
module top_module (
    input clk,
    input d,
    output q
);
    reg [1:0] status;
    
    always @(posedge clk) begin
        status[0] <= d;
    end
    
    always @(negedge clk) begin
        status[1] <= d; 
    end
    
    assign q = (clk) ? status[0] : status[1];
    
endmodule

*****2021.5.21

Counters

Counter
module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire [3:0] Q0,Q1,Q2;
    assign c_enable[0] = 1;
    assign c_enable[1] = (Q0=='d9);
    assign c_enable[2] = (Q0=='d9 && Q1=='d9);
    assign OneHertz = (Q0=='d9 && Q1=='d9 && Q2=='d9);
    bcdcount counter0 (clk, reset,c_enable[0], Q0);
    bcdcount counter1 (clk, reset,c_enable[1], Q1);
    bcdcount counter2 (clk, reset,c_enable[2],Q2);


endmodule

4-digit decimal counter
使用组合的形式
module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    //always@(posedge clk)
    assign ena[1] = (q[3:0]=='d9);
    assign ena[2] = (q[3:0]=='d9 && q[7:4] =='d9);
    assign ena[3] = (q[3:0]=='d9 && q[7:4] =='d9 && q[11:8] == 'd9);
    
    
    ten_counters t1(q[3:0],1,clk,reset);
    ten_counters t2(q[7:4],ena[1],clk,reset);
    ten_counters t3(q[11:8],ena[2],clk,reset);
    ten_counters t4(q[15:12],ena[3],clk,reset);
endmodule

module ten_counters(
    output [3:0] q,
	input enable,
    input clk,
	input reset
);
    always @(posedge clk)
        if(reset)
            q <= 0;
    	else
            if(enable)
                begin
                if(q == 'd9)
                    begin
                    q <= 0;
                 //   ena <= 1;
                    end
                else
                    begin
                    q <= q + 1;
                 //   ena <= 0;
                    end
                end
endmodule
module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    initial 
        pm =0;
        
    wire ena1,ena2;

    
    assign ena1 = (ss == {4'b0101,4'b1001});
    assign ena2 = (ss == {4'b0101,4'b1001} && mm =={4'b0101,4'b1001});
    assign pm =(ss == {4'b0101,4'b1001} && mm =={4'b0101,4'b1001} && hh=={4'b0001,4'b0001} )? !pm:pm;
    //always @(posedge clk)
        //  if(ss =='d59 & &&   == 59)
    
    counters_60 counter_s(ss,reset,clk,ena);
    counters_60 counter_m(mm,reset,clk,ena1);
    counters_12 counter_h(hh,reset,clk,ena2);
    
    

endmodule




module counters_10( //10进制
    output [3:0] q,
    input reset,
    input clk,
    input ena
);
    always@(posedge clk)
        if(reset)
            q <= 'd00;
    	else
            if(ena)
                if(q == 'd9)
                    q <= 0;
    			else
                    q <= q+1;
endmodule

module counters_6( 
    output [3:0] q,
    input reset,
    input clk,
    input ena
);
    always@(posedge clk)
        if(reset)
            q <= 'd0;
    	else
            if(ena)
                if(q == 'd5)
                    q <= 0;
    			else
                    q <= q+1;
endmodule


module counters_12( 
    output [7:0] qq,
    input reset,
    input clk,
    input ena
);
    initial qq =8'h0;
    wire [3:0] q;
    always@(posedge clk)
        if(reset)
            q <= 4'h12;
    	else
            if(ena)
                if(q == 4'h12)
                    q <= 1;
    			else
                    q <= q+1;
    
    always@(*)
        if(q < 4'h10)
            qq = q;
    	else
            case(q)
                4'h10:qq = {4'h1,4'h0};
                4'h11:qq = {4'h1,4'h1};
                4'h12:qq = 8'b00010010;
                //default: qq ='h0;
        	endcase
endmodule

module counters_60(
    output [7:0] q,
    input reset,
    input clk,
    input ena);
    wire ena1;
    assign ena1 = (q[3:0]=='d9);
    counters_6(q[7:4],reset,clk,ena1);
    counters_10(q[3:0],reset,clk,ena);
    
endmodule

******5.2

Shift Registers

4-bit shift register
module top_module(
    input clk,
    input areset,  // async active-high reset to zero
    input load,
    input ena,
    input [3:0] data,
    output reg [3:0] q); 
    always @( posedge clk or posedge areset)
        if(areset)
            q <= 4'h0;
    	else
            begin
            if(load)
                q <= data;
                else 
                    if(ena)
                   		 q <={{1'b0},q[3:1]};                    
           end                
endmodule

Left/right rotator
module top_module(
    input clk,
    input load,
    input [1:0] ena,
    input [99:0] data,
    output reg [99:0] q); 
    always@(posedge clk)
        if(load)
            q <= data;
    	else begin
            case(ena)
                2'd1:q<={q[0],q[99:1]};//shift right
                2'd2:q<={q[98:0],q[99]};//shift left
                default: q <= q;
            endcase
        end
endmodule

Left/right arithmetic shift by 1 or 8(算术移位)
一、对于有符号数 int
正数,左移直接丢弃最高位,在低位补对应个数的0;
正数,右移直接丢弃最低位,在高位补对应个数的0;
负数,左移直接丢弃最高位,在低位补对应个数的0;
负数,右移直接丢弃最低位,在高位补对应个数的1
二、对于无符号数 unsigned int
左移直接丢弃最高位,在低位补对应个数的0;
右移直接丢弃最低位,在高位补对应个数的0,即使最高位原来是1;

三、总结
算术右移:最高位填充符号位。正数填充0,负数填充1
逻辑右移:最高位填充0
左移都是补0
refer:https://blog.csdn.net/vainfanfan/article/details/87541575
module top_module(
    input clk,
    input load,
    input ena,
    input [1:0] amount,
    input [63:0] data,
    output reg [63:0] q); 

    always@(posedge clk)
        if(load)
            q<=data;
    else if(ena) begin
        case(amount)
            2'b00:q<={q[62:0],1'b0};
            2'b01:q<={q[55:0],{8{1'b0}}};
            2'b10:q<={q[63],q[63:1]};
            2'b11:q<={{8{q[63]}},q[63:8]};
        endcase
    end
endmodule

5-bit LFSR
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
    always@(posedge clk)
        if(reset)
            q<=1;
    	else 
            q<={q[0]^1'b0,q[4],q[3]^q[0],q[2:1]};       
endmodule

3-bit LFSR
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q
    always@(posedge KEY[0])
        if(KEY[1])
            LEDR <= SW;
    	else begin
            LEDR <= {LEDR[1]^LEDR[2],LEDR[0],LEDR[2]};
        end

endmodule

32-bit LFSR (begin-end中的非阻塞赋值是并行的?)
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output [31:0] q
); 
    always@(posedge clk)
        if(reset)
            q<=32'h1;
    	else begin
            q<={q[0],q[31:1]};
            q[31]<=q[0]^1'b0;
            q[21]<=q[22]^q[0];
            q[1]<=q[2]^q[0];
            q[0]<=q[1]^q[0];
        end

endmodule

Shift register2
module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //


always@(posedge KEY[0])
    case(KEY[2])
        1:LEDR<=SW;
        0:begin
            case(KEY[1])
                1:LEDR<={KEY[3],LEDR[3:1]};
                default:;
            endcase
        end
        default:;
    endcase


endmodule

3-input LUT
module top_module (
    input clk,
    input enable,
    input S,
    input A, B, C,
    output Z ); 
    wire [7:0] Q;
    always@(posedge clk)
        if(enable)
            Q<={Q[6:0],S};
    	else
            ;
    
    always@(*)
        case({A,B,C})
            3'd0:Z = Q[0];
            3'd1:Z = Q[1];
            3'd2:Z = Q[2];
            3'd3:Z = Q[3];
            3'd4:Z = Q[4];
            3'd5:Z = Q[5];
            3'd6:Z = Q[6];
            3'd7:Z = Q[7];
            default: ;
        endcase
            
            

endmodule

More Circuits

Rule 90
module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q ); 
    integer i;
    always@(posedge clk)
        if(load)
            q<=data;
    else
        begin
            q[0]<=q[1];
            q[511]<=q[510];
        for(i=1;i<=510;i++)
            q[i] <= q[i-1] ^ q[i+1];
        end
    

endmodule

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值