文章目录
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