1. 四选一多路器
较为基础根据sel进行输出选择。
2. 异步复位T触发器
T触发器:
Qn+1 = T Qn ' +T ' Qn= T⊕Qn 即每个CLK,T为0保持,T为1翻转。
`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q
);
//*************code***********//
reg databuffer;
always@(posedge clk or negedge rst)
if(!rst)
databuffer<=0;
else
databuffer<=data?(~databuffer):databuffer;
always@(posedge clk or negedge rst)
if(!rst)
q<=0;
else
q<=databuffer?(~q):q;
//*************code***********//
endmodule
同步复位:复位受到CLK控制
异步复位:复位不受CLK控制
3. 奇偶校验
二进制代码的数位中“1”的个数是奇数或偶数来进行校验
用异或 (^sel)来判断是否是奇校验
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
wire checkbuff;
assign checkbuff = (sel)?^bus:~(^bus);
assign check = checkbuff;
//*************code***********//
endmodule
4. 移位运算与乘法
`timescale 1ns/1ns
module multi_sel (
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//
reg [1:0] cnt;
reg [7:0] reg_d;
always@(posedge clk or negedge rst)
if(rst == 1'b0)
cnt <= 2'd0;
else if(cnt == 2'd3)
cnt <= 2'd0;
else
cnt <= cnt + 1'b1;
always@(posedge clk or negedge rst)
if(rst == 1'b0)begin
reg_d <= 8'd0;
input_grant <= 1'b0;
end
else if(cnt == 2'd0)begin
reg_d <= d;
input_grant <= 1'b1;
end
else begin
reg_d <= reg_d;
input_grant <= 1'b0;
end
always@(posedge clk or negedge rst)
if(rst == 1'b0)
out <= 11'd0;
else case (cnt)
2'd0 : out <= d;
2'd1 : out <= (reg_d<<2)-reg_d;
2'd2 : out <= (reg_d<<3)-reg_d;
2'd3 : out <= (reg_d<<3);
default : out <= 11'd0;
endcase
//*************code***********//
endmodule
8. generate...for...简化
`timescale 1ns/1ns
module gen_for_module(
input [7:0] data_in,
output [7:0] data_out
);
genvar gv_i;
generate
for(gv_i=0;gv_i<8;gv_i=gv_i+1)
begin:test
assign data_out [gv_i] = data_in [7-gv_i];
end
endgenerate
endmodule
11. 4位数值比较器电路
结构化描述方式: 是使用实例化低层次模块的方法,即调用其他已经定义过的低层次模块对整个电路的功能进行描述,或者直接调用Verilog内部预先定义的基本门级元件描述电路的结构。
数据流描述方式: 是使用连续赋值语句(assign)对电路的逻辑功能进行描述,该方式特别便于对组合逻辑电路建模。
行为级描述方式: 是使用过程块语句结构(always)和比较抽象的高级程序语句对电路的逻辑功能进行描述。
此题只能用门电路,即与,或,非等等
1位比较器:
module compare_1(
input A,
input B,
output Y2,//A>B
output Y1,//A=B
output Y0 //A<B
);
assign Y2 = A & (!B);
assign Y0 = (!A) & B;
assign Y1 = !(Y2 | Y0);
endmodule
`timescale 1ns/1ns
module comparator_4(
input [3:0] A ,
input [3:0] B ,
output wire Y2 , //A>B
output wire Y1 , //A=B
output wire Y0 //A<B
);
// wire [3:0] A_buffer,B_buffer;
// assign A_buffer=A;
// assign B_buffer=B;
// assign Y1=(A_buffer==B_buffer)?1:0;
// assign Y2=(A_buffer>B_buffer)?1:0;
// assign Y0=(A_buffer<B_buffer)?1:0;
wire W_y2[0:3];
wire W_y1[0:3];
wire W_y0[0:3];
genvar gen_i;
for (gen_i = 0; gen_i < 4; gen_i = gen_i + 1) begin
compare_1 compare_1_u(
.A (A[gen_i] ),
.B (B[gen_i] ),
.Y2(W_y2[gen_i]),//A>B
.Y1(W_y1[gen_i]),//A=B
.Y0(W_y0[gen_i]) //A<B
);
end
assign Y2 = W_y2[3] | ((W_y1[3]) & (W_y2[2])) | ((W_y1[3]) & (W_y1[2]) & (W_y2[1])) | ((W_y1[3]) & (W_y1[2]) & (W_y1[1]) & (W_y2[0]));
assign Y0 = W_y0[3] | ((W_y1[3]) & (W_y0[2])) | ((W_y1[3]) & (W_y1[2]) & (W_y0[1])) | ((W_y1[3]) & (W_y1[2]) & (W_y1[1]) & (W_y0[0]));
assign Y1 = W_y1[3] & W_y1[2] & W_y1[1] & W_y1[0];
endmodule
module compare_1(
input A,
input B,
output Y2,//A>B
output Y1,//A=B
output Y0 //A<B
);
assign Y2 = A & (!B);
assign Y0 = (!A) & B;
assign Y1 = !(Y2 | Y0);
endmodule
12. 4位加法器设计
加法器中半加器为:
assign S=A^B;
assign C_out = A&B;
全加器为:
assign S = A^B^C_i;
assign C_o = A&B|C_i&(a^b);
我之前的思路为设计RCA,行波进位加法器,即将全加器串联起来:
module rca #(
parameter width = 4
)(
input [width-1:0] A,
input [width-1:0] B,
output [width-1:0] S,
input C_i,
output C_o
);
wire [width:0] C;
genvar i;
generate
for (i=0; i<width; i=i+1)begin
full_adder myadder(
.A (A[i]),
.B (B[i]),
.C_i (C[i]),
.S (S[i]),
.C_o (C[i+1]),
);
end
endgenerate
assign C[0] = C_i;
assign C_o = C[width];
endmodule
按照此思路设计的代码如下:
`timescale 1ns/1ns
module lca_4(
input [3:0] A_in ,
input [3:0] B_in ,
input C_1 ,
output wire CO ,
output wire [3:0] S
);
wire [4:0]C_IN;
// reg [3:0]COO;
assign C_IN[0]=C_1;
genvar i;
generate
for(i=0;i<4;i=i+1)
begin
lca_1 mylca(.a_0(A_in[i]),.b_0(B_in[i]),.ci_0(C_IN[i]),.s_0(S[i]),.co_0(C_IN[i+1]));
end
endgenerate
assign CO=C_IN[4];
endmodule
module lca_1(
input a_0,
input b_0,
input ci_0,
output wire co_0,
output wire s_0
);
// assign s = a^b^cin;
// assign cout = a&b | (cin & (a^b));
assign s_0=a_0^b_0^ci_0;
assign co_0=a_0&b_0|(ci_0&(a_0^b_0));
endmodule
此种方式由于多位串联,很可能产生时延,导致数据接受异常,因此设计另一种加法器方式:
LCA,超前进位加法器,思路为并行计算进位。
此处新开一节记录加法器:加法器笔记。
超前进位加法器的设计思路如此链接:超前进位加法器。
超前进位加法器并行计算进位Ck。
assign S = A^B^C_i;
assign C_o = A&B|C_i&(a^b);
P = A^B;
G = A&B;
转换公式变为:
Si=Pi^ci-1;
ci=Gi+ci-1Pi;
c0=cin;
cout=cN;
根据这个原理,开始加法器设计!
13. 优先译码器①
考察case,casez,casex的用法:
-
在case语句中,敏感表达式中与各项值之间的比较是一种全等比较,每一位都相同才认为匹配。
-
在casez语句中,如果分支表达式某些位的值为高阻z,那么对这些位的比较就会忽略,不予考虑,而只关注其他位的比较结果。
-
在casex语句中,则把这种处理方式进一步扩展到对x的处理,即如果比较双方有一方的某些位的值是z或x,那么这些位的比较就不予考虑。
15.优先编码器
此题仅为简单测试,我也不知道和之前有什么区别,应该是case,casez,casex的使用
`timescale 1ns/1ns
module encoder_83(
input [7:0] I ,
input EI ,
output wire [2:0] Y ,
output wire GS ,
output wire EO
);
reg [2:0] Ybuf;
always@(*)
begin
casex(I)
8'b0000_0000:Ybuf=3'd0;
8'b0000_0001:Ybuf=3'd0;
8'b0000_001x:Ybuf=3'd1;
8'b0000_01xx:Ybuf=3'd2;
8'b0000_1xxx:Ybuf=3'd3;
8'b0001_xxxx:Ybuf=3'd4;
8'b001x_xxxx:Ybuf=3'd5;
8'b01xx_xxxx:Ybuf=3'd6;
8'b1xxx_xxxx:Ybuf=3'd7;
default:Ybuf=3'd0;
endcase
end
assign EO=(&(~I))&EI;
assign GS=I&&EI;
assign Y=(EI)?Ybuf:3'd0;
endmodule