目录
1、四选一多路器
`timescale 1ns/1ns
module mux4_1(
input [1:0]d1,d2,d3,d0,
input [1:0]sel,
output[1:0]mux_out
);
//*************code***********//
reg[1:0] mux_out_reg;
assign mux_out = mux_out_reg;
always@(*) begin
case(sel)
2'b00: mux_out_reg = d3;
2'b01: mux_out_reg = d2;
2'b10: mux_out_reg = d1;
2'b11: mux_out_reg = d0;
default:
mux_out_reg = d3;
endcase
end
//*************code***********//
endmodule
在使用例化模块进行编程时经常会遇到这两种类型的数据相连接的情况
wire型数据:在assign左侧被赋值;
reg型数据:在always@的左侧被赋值;
两者均能在assign和always@的右侧被使用。
*/
2、异步复位串联触发器
`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q
);
//*************code***********//
//T触发器如果是输入1,则上一周期输出取反
reg q1;
always@(posedge clk or rst)
begin
if(!rst) begin
q1<=1'b0;
end
else begin
if(data)
q1<=~q1;
end
end
always@(posedge clk or rst)
begin
if(!rst) begin
q<=1'b0;
end
else begin
if(q1)
q<=~q;
end
end
//*************code***********//
endmodule
3、奇偶校验
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
assign check=sel?^bus:~^bus;
//*************code***********//
endmodule
4、移位运算与乘法
利用有限状态机:初状态也加入状态,然后在4个状态中循环,always@(state) 中不是always@(*),就会保持当时的输入状态循环,不然就是实施的采集输入的d。
`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//
parameter T0=3'b000,T1=3'b001,T3=3'b010,T7=3'b011,T8=3'b100;
reg [7:0]din;
reg [3:0]state;
reg [3:0]next_state;
reg rst_n,rff1;
always@(posedge clk or rst) begin
if(!rst)
{rst_n,rff1}<=2'b0;
else
{rst_n,rff1}<={rff1,1'b1};
end
always@(posedge clk or rst_n)begin
if(!rst_n)
state<=0;
else
state<=next_state;
end
always@(state) begin
case(state)
T0:begin
out<=0;
input_grant<=0;
next_state<=T1;
end
T1:begin
din<=d;
next_state<=T3;
out<=d;
input_grant<=1;
end
T3:begin
next_state<=T7;
out<=din+{din,1'b0};
input_grant<=0;
end
T7:begin
next_state<=T8;
out<=din+{din,1'b0}+{din,2'b0};
input_grant<=0;
end
T8:begin
next_state<=T1;
out<={din,3'b0};
input_grant<=0;
end
default:next_state<=T0;
endcase
end
//*************code***********//
endmodule
rff1连接高电平,
5、拆分与运算
`timescale 1ns/1ns
module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,
output [4:0]out,
output validout
);
//*************code***********//
reg [3:0]num1,num2,num3,num4;
reg [4:0]out_t;
reg validout_t;
always@(posedge clk or rst) begin
if(!rst) begin
out_t<=0;
validout_t<=0;
end
else begin
case(sel)
0:begin
num1<=d[3:0];
num2<=d[7:4];
num3<=d[11:8];
num4<=d[15:12];
out_t<=0;
validout_t<=0;
end
1:begin
out_t<=num1+num2;
validout_t<=1;
end
2:begin
out_t<=num1+num3;
validout_t<=1;
end
3:begin
out_t<=num1+num4;
validout_t<=1;
end
endcase
end
end
assign validout=validout_t;
assign out=out_t;
//*************code***********//
endmodule
6、 多功能数据处理器
`timescale 1ns/1ns
module data_select(
input clk,
input rst_n,
input signed[7:0]a,
input signed[7:0]b,
input [1:0]select,
output reg signed [8:0]c
);
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
c<=0;
end
else begin
case(select)
0:begin
c<=a;
end
1:begin
c<=b;
end
2:begin
c<=a+b;
end
3:begin
c<=a-b;
end
endcase
end
end
endmodule
注意:negedge rst_n并不会触发;
- 改成异步复位同步释放如下:
rst_n为低,执行{rst,rff1}<=2'b0;第二个always中的rst动作,输出异步复位值。0
rst_n释放为高,执行{rst,rff1}<={rff1,1'b1};rst依然为低,rff1为高,当posedge来临时,此时rst_n为高,再次执行{rst,rff1}<={rff1,1'b1}; rst为高,第二个always中的rst动作为高,输出非复位的结果。
`timescale 1ns/1ns
module data_select(
input clk,
input rst_n,
input signed[7:0]a,
input signed[7:0]b,
input [1:0]select,
output reg signed [8:0]c
);
reg rst,rff1;
always@(posedge clk or rst_n) begin
if(!rst_n)
{rst,rff1}<=2'b0;
else
{rst,rff1}<={rff1,1'b1};
end
always@(posedge clk or rst) begin
if(!rst) begin
c<=0;
end
else begin
case(select)
0:begin
c<=a;
end
1:begin
c<=b;
end
2:begin
c<=a+b;
end
3:begin
c<=a-b;
end
endcase
end
end
endmodule
7、generater...for语句简化代码
注意:1、genvar一个参数,2、然后for循环的写法,3、起个名字
`timescale 1ns/1ns
module gen_for_module(
input [7:0] data_in,
output [7:0] data_out
);
genvar i;
generate for(i=0;i<8;i=i+1)
begin:bit_reverse//起个名字
assign data_out[i]=data_in[7-i];
end
endgenerate
endmodule
9、使用子模块实现三输入数的大小比较
`timescale 1ns/1ns
module main_mod(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
input [7:0]c,
output [7:0]d
);
wire [7:0] temp0,temp1;
sub_mod sd0(.a(a),.b(b),.c(temp0),.clk(clk),.rst_n(rst_n));
sub_mod sd1(.a(a),.b(c),.c(temp1),.clk(clk),.rst_n(rst_n));
sub_mod sd2(.a(temp0),.b(temp1),.c(d),.clk(clk),.rst_n(rst_n));
endmodule
module sub_mod(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
output reg [7:0]c
);
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
c<=0;
else
c<=a>b?b:a;
end
endmodule
10、函数
返回类型缺省就是reg类型的
`timescale 1ns/1ns
module function_mod(
input [3:0]a,
input [3:0]b,
input clk,
input rst_n,
output [3:0]c,
output [3:0]d
);
assign c=big2sall(a);
assign d=big2sall(b);
function [3:0]big2sall;
input [3:0]datain;
integer i;
for (i=0;i<4;i=i+1)
begin:re
big2sall[i]=datain[3-i];
end
endfunction
endmodule
11、组合逻辑
注意:找到使Y输出1的条件,多个条件满足时用逻辑并,注意用符号
`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
);
assign Y2=(A[3]>B[3]) | ((A[3]==B[3])&&(A[2]>B[2])) |((A[3]==B[3])&&(A[2]==B[2])&&(A[1]>B[1]))| ((A[3]==B[3])&&(A[2]==B[2])&&(A[1]==B[1])&&(A[0]>B[0]));
assign Y1=(A[3]==B[3])&&(A[2]===B[2])&&(A[1]==B[1])&&(A[0]==B[0]);
assign Y0=(~Y2)&(~Y1);
endmodule
12、超前进位加法器
注意,加号用逻辑与表示
`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 [3:0]G;
wire [3:0]P;
assign G[0]=A_in[0]&B_in[0];
assign G[1]=A_in[1]&B_in[1];
assign G[2]=A_in[2]&B_in[2];
assign G[3]=A_in[3]&B_in[3];
assign P[0]=A_in[0]&B_in[0];
assign P[1]=A_in[1]&B_in[1];
assign P[2]=A_in[2]&B_in[2];
assign P[3]=A_in[3]&B_in[3];
wire [3:0]C;
assign S[0]=P[0]^C_1;
assign S[1]=P[1]^C[0];
assign S[2]=P[2]^C[1];
assign S[3]=P[3]^C[2];
assign CO=C[3];
assign C[0]=G[0] |P[0]&C_1;
assign C[1]=G[1] |P[1]&C[0];
assign C[2]=G[2] |P[2]&C[1];
assign C[3]=G[3] |P[3]&C[2];
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
);
assign {CO,S}=A_in+B_in+C_1;
endmodule
13、优先编码器
注意:? 为不管是0还是1
`timescale 1ns/1ns
module encoder_0(
input [8:0] I_n ,
output reg [3:0] Y_n
);
always@(*) begin
casex (I_n)
9'b1_1111_1111: Y_n = 4'b1111;
9'b0_xxxx_xxxx: Y_n = 4'b0110;
9'b1_0xxx_xxxx: Y_n = 4'b0111;
9'b1_10xx_xxxx: Y_n = 4'b1000;
9'b1_110x_xxxx: Y_n = 4'b1001;
9'b1_1110_xxxx: Y_n = 4'b1010;
9'b1_1111_0xxx: Y_n = 4'b1011;
9'b1_1111_10xx: Y_n = 4'b1100;
9'b1_1111_110x: Y_n = 4'b1101;
9'b1_1111_1110: Y_n = 4'b1110;
default: Y_n = 4'b0000;
endcase
end
endmodule
关于case
、casez
和casex
,三者都是可以综合的。case
进行全等匹配,casez
忽略?
或z
对应的位进行匹配,casex
忽略x
、?
或z
对应的位进行匹配。
比如:输入信号9'b0_1001_0100,第一位匹配上,第二位与x匹配必为1,第三位与x匹配必为1....,全匹配上了之后,就选择这个输出(9'b0_xxxx_xxxx: Y_n = 4'b0110;)
14、3-8译码器
- 加一个组合逻辑②请使用3-8译码器①和必要的逻辑门实现函数L=(~A)·C+A·B
`timescale 1ns/1ns
module decoder_38(
input E1_n ,
input E2_n ,
input E3 ,
input A0 ,
input A1 ,
input A2 ,
output wire Y0_n ,
output wire Y1_n ,
output wire Y2_n ,
output wire Y3_n ,
output wire Y4_n ,
output wire Y5_n ,
output wire Y6_n ,
output wire Y7_n
);
wire E ;
assign E = E3 & ~E2_n & ~E1_n;
assign Y0_n = ~(E & ~A2 & ~A1 & ~A0);
assign Y1_n = ~(E & ~A2 & ~A1 & A0);
assign Y2_n = ~(E & ~A2 & A1 & ~A0);
assign Y3_n = ~(E & ~A2 & A1 & A0);
assign Y4_n = ~(E & A2 & ~A1 & ~A0);
assign Y5_n = ~(E & A2 & ~A1 & A0);
assign Y6_n = ~(E & A2 & A1 & ~A0);
assign Y7_n = ~(E & A2 & A1 & A0);
endmodule
module decoder0(
input A ,
input B ,
input C ,
output wire L
);
wire Y0_n ;
wire Y1_n ;
wire Y2_n ;
wire Y3_n ;
wire Y4_n ;
wire Y5_n ;
wire Y6_n ;
wire Y7_n ;
decoder_38 U0(
.E1_n (1'b0),
.E2_n (1'b0),
.E3 (1'b1),
.A0 (C),
.A1 (B),
.A2 (A),
.Y0_n (Y0_n),
.Y1_n (Y1_n),
.Y2_n (Y2_n),
.Y3_n (Y3_n),
.Y4_n (Y4_n),
.Y5_n (Y5_n),
.Y6_n (Y6_n),
.Y7_n (Y7_n)
);
assign L = ~(Y1_n & Y3_n & Y6_n & Y7_n);
endmodule
15、四选一多路选择器
16、 数据选择器实现逻辑电路
表达式中要的留下,不要的去掉。
`timescale 1ns/1ns
module data_sel(
input S0 ,
input S1 ,
input D0 ,
input D1 ,
input D2 ,
input D3 ,
output wire Y
);
assign Y = ~S1 & (~S0&D0 | S0&D1) | S1&(~S0&D2 | S0&D3);
endmodule
module sel_exp(
input A ,
input B ,
input C ,
output wire L
);
data_sel d1(.S0(A),.S1(B),.D0(0),.D1(~C),.D2(C),.D3(1),.Y(L));
endmodule
17、三段式有限状态机,mealy
`timescale 1ns/1ns
module seq_circuit(
input A ,
input clk ,
input rst_n,
output wire Y
);
parameter s00=2'b00,s01=2'b01,s10=2'b10,s11=2'b11;
reg [1:0]state,next_state;
reg yy;
assign Y=yy;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
state<=0;
else
state<=next_state;
end
always@(*) begin
case(state)
s00:begin
if(A==0)
next_state<=s01;
else
next_state<=s11;
end
s01:begin
if(A==0)
next_state<=s10;
else
next_state<=s00;
end
s10:begin
if(A==0)
next_state<=s11;
else
next_state<=s01;
end
s11:begin
if(A==0)
next_state<=s00;
else
next_state<=s10;
end
default:next_state<=s00;
endcase
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
yy<=0;
else begin
case(next_state)
s00:yy<=0;
s01:yy<=0;
s10:yy<=0;
s11:yy<=1;
endcase
end
end
endmodule
错误方式:主要是第三段,A无论是不是1,输出都是0
`timescale 1ns/1ns
module seq_circuit(
input A ,
input clk ,
input rst_n,
output wire Y
);
parameter s00=2'b00,s01=2'b01,s10=2'b10,s11=2'b11;
reg [1:0]state,next_state;
reg yy;
assign Y=yy;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
state<=0;
else
state<=next_state;
end
always@(*) begin
case(state)
s00:begin
if(A==0)
next_state<=s01;
else
next_state<=s11;
end
s01:begin
if(A==0)
next_state<=s10;
else
next_state<=s00;
end
s10:begin
if(A==0)
next_state<=s11;
else
next_state<=s01;
end
s11:begin
if(A==0)
next_state<=s00;
else
next_state<=s10;
end
default:next_state<=s00;
endcase
end
always@(state or A) begin
case(state)
s00:if(A==0)
yy<=0;
else
yy<=0;
end
s01:if(A==0)
yy<=0;
else
yy<=0;
end
s10:if(A==0)
yy<=0;
else
yy<=0;
end
s11:if(A==0)
yy<=1;
else
yy<=1;
end
endcase
end
endmodule
18、三段式状态机
次态逻辑
状态记忆
输出逻辑
`timescale 1ns/1ns
module seq_circuit(
input C ,
input clk ,
input rst_n,
output wire Y
);
reg yy;
reg [1:0]state,next_state;
parameter s00=2'b00,s01=2'b01,s10=2'b10,s11=2'b11;
assign C=yy;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
state<=0;
else
state<=next_state;
end
always@(*) begin
case(state)
s00:begin
if(C==1)
next_state<=s01;
else
next_state<=s00;
end
s01:begin
if(C==1)
next_state<=s01;
else
next_state<=s11;
end
s10:begin
if(C==1)
next_state<=s10;
else
next_state<=s00;
end
s11:begin
if(C==1)
next_state<=s10;
else
next_state<=s11;
end
default: next_state<=s00;
endcase
end
always@(*) begin
case(state)
s00:yy<=0;
s01:yy<=0;
s10:begin
if(C==1)
yy<=1;
else
yy<=0;
end
s11:yy<=0;
endcase
end
endmodule
注意:第二段是组合逻辑,第三段可组合case(state)可时序case(next_state)
最后一句代码还是很重要的。
`timescale 1ns/1ns
module seq_circuit(
input C ,
input clk ,
input rst_n,
output wire Y
);
reg [1:0] curr_state;
reg [1:0] next_state;
// one step
always @ (posedge clk&nbs***bsp;negedge rst_n)
begin
if( ~rst_n ) begin
curr_state <= 2'b00;
end
else begin
curr_state <= next_state;
end
end
// two step
always @ (*)
begin
case(curr_state)
2'b00 : next_state = (C == 1'b1) ? 2'b01 : 2'b00;
2'b01 : next_state = (C == 1'b1) ? 2'b01 : 2'b11;
2'b10 : next_state = (C == 1'b1) ? 2'b10 : 2'b00;
2'b11 : next_state = (C == 1'b1) ? 2'b10 : 2'b11;
default : next_state = 2'b00;
endcase
end
assign Y = ((curr_state == 2'b11) | ((curr_state == 2'b10)&&(C == 1'b1)) )? 1 : 0;
endmodule