当前位置:   article > 正文

牛客网-刷题-Verilog入门

牛客网-刷题-Verilog入门

Verilog入门

Part one 基础语法

VL1 四选一多路器

// VL1 四选一多路器
// 这一题主要得知道,always块里赋值的话都得是reg型
// 不管是阻塞赋值还是非阻塞赋值
`timescale 1ns/1ns
module mux4_1(
input      [1:0]d1,d2,d3,d0,sel,
output reg [1:0]mux_out
);
always @ (*)begin
    case(sel)
    2'd0: mux_out = d3;
    2'd1: mux_out = d2;
    2'd2: mux_out = d1;
    2'd3: mux_out = d0;
    endcase
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

VL2 用verilog实现两个串联的异步复位的T触发器

// VL2 用verilog实现两个串联的异步复位的T触发器
// 没太理解那个波形图,但是T触发器就是这种,1翻转0不变
// 学会用if else if else语句
// 然后这个题的复位还是低电平
`timescale 1ns/1ns
module Tff_2 (
input      data,clk,rst,
output reg q
);
reg q0;
always @ (posedge clk or negedge rst) begin
    if(~rst)      q0 <= 1'd0;
    else if(data) q0 <= ~q0;
    else          q0 <= q0;
end
always @ (posedge clk or negedge rst) begin
    if(~rst)      q <= 1'd0;
    else if(q0)   q <= ~q;
    else          q <= q;
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

VL3 奇偶校验

// VL3 奇偶校验(该题通过的答案是错的)
// 若有奇数个1,奇校验为0,偶校验为1
// 若有偶数个1,奇校验为1,偶校验为0
// 奇校验:添加校验位后,数位中的1总数是奇数
// 偶校验:添加校验位后,数位中的1总数是偶数
// 思路位对bus按位,异或若有奇数个1则为1,那么奇校验
// 然后结合sel,sel为0是奇校验,
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input        sel,
output       check
);
assign check = sel ? ^bus : ~(^bus);
// assign check = sel ? ~(^bus) : ^bus; // 真的正确答案
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

VL4 移位运算与乘法

// VL4 移位运算与乘法(稍有不规范)
// 建议是分段式写always块,这里没这么做
// 关于在非阻塞赋值的右侧使用,逻辑判断/三目运算符
// 其实always块以if else判断可以不用begin end
// 这题的测试文件还没写
`timescale 1ns/1ns
module multi_sel(
input      [7:0]  d,
input             clk,rst,
output reg        input_grant,
output reg [10:0] out
);
reg [1:0] cnt;
reg [7:0] d0;
always @ (posedge clk or negedge rst)
    if(~rst) begin
        out         <= 11'd0;
        d0          <= 8'd0;
        cnt         <= 2'd0;
        input_grant <= 1'd0;
    end
    else begin
        cnt         <= cnt + 2'd1;
        input_grant <= (cnt==2'd0);
        d0          <= (cnt==2'd0) ? d : d0;
        case(cnt) 
        2'd0: out <= d;
        2'd1: out <= d0 + {d0,1'd0};
        2'd2: out <= d0 + {d0,1'd0} + {d0,2'd0};
        2'd3: out <= {d0,3'd0};
        endcase
    end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

VL5 位拆分与运算

// VL5 位拆分与运算
// 和上题差不多,更简单点
`timescale 1ns/1ns
module data_cal(
input             clk,
input             rst,
input      [15:0] d,
input      [1:0]  sel,
output reg [4:0]  out,
output reg        validout
);
reg [15:0] d0;
always @ (posedge clk or negedge rst)begin
    if(~rst)begin
        d0       <= 16'd0;
        out      <= 5'd0;
        validout <= 1'd0;
    end
    else begin
        case(sel)
        2'd0: begin d0<=d; out<=5'd0; validout<=1'd0; end
        2'd1: begin out<=d0[3:0]+d0[7:4]; validout<=1'd1;end
        2'd2: begin out<=d0[3:0]+d0[11:8]; validout<=1'd1;end
        2'd3: begin out<=d0[3:0]+d0[15:12]; validout<=1'd1;end
        endcase
    end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

VL6 多功能数据处理器

// VL6 多功能数据处理器
// 和上题差不多,更简单点
`timescale 1ns/1ns
module data_select(
    input                   clk,rst_n,
    input      signed [7:0] a,b,
    input             [1:0] select,
    output reg signed [8:0] c
);
always @ (posedge clk or negedge rst_n)begin
    if(~rst_n)begin
        c <= 9'd0;
    end
    else begin
        case(select)
        2'd0: c <= a;
        2'd1: c <= b;
        2'd2: c <= a + b;
        2'd3: c <= a - b;
        endcase
    end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

VL7 求两个数的差值

// VL7 求两个数的差值
// 没啥特别,用if else if代替嵌套if else
`timescale 1ns/1ns
module data_minus(
    input            clk,rst_n,
    input      [7:0] a,b,
    output reg [8:0] c
);
always @ (posedge clk or negedge rst_n)begin
    if(~rst_n)   c <= 9'd0;
    else if(a>b) c <= a-b;
    else         c <= b-a;
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

VL8 使用generate…for语句简化代码

// VL8 使用generate…for语句简化代码
// generate语法的使用,里边搭配for循环
`timescale 1ns/1ns
module gen_for_module( 
    input  [7:0] data_in,
    output [7:0] data_out
);
generate genvar i;
    for(i=0;i<8;i=i+1)begin:gen
        assign data_out[i]=data_in[7-i];
    end
endgenerate
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

VL9 使用子模块实现三输入数的大小比较

// VL9 使用子模块实现三输入数的大小比较
// 使用if else if代替嵌套 if else
// 新的模块例化方式(当知道模块内部信号定义顺序时可以这么写)
// 关于这个题一定要要用三次比较!!!!!
// 如果只用两次比较,由于并行比较,第一级输出和第二级输入不是同clk
`timescale 1ns/1ns
module main_mod(
    input        clk,rst_n,
    input  [7:0] a,b,c,
    output [7:0] d
);
    wire [7:0]i,j;
    slave_mod mod1(clk,rst_n,a,b,i);
    slave_mod mod2(clk,rst_n,a,c,j);
    slave_mod mod3(clk,rst_n,i,j,d); 
endmodule

module slave_mod(
    input            clk,rst_n,
    input      [7:0] in_1,in_2,
    output reg [7:0] out
);

always @ (posedge clk or negedge rst_n)begin
    if(~rst_n)         out <= 8'd0;
    else if(in_1<in_2) out<=in_1;
    else               out<=in_2;
end
endmodule


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

VL10 使用函数实现数据的大小端转换

// VL10 使用函数实现数据的大小端转换
// 这里有复位,题目意思就是复位的时候输出的值为0
// 学习function的用法,有时间结合task语法一起学一下!!!!!!
`timescale 1ns/1ns
module function_mod(
    input        clk,rst_n,
    input  [3:0] a,b,
    output [3:0] c,d
);
function  [3:0] f1;
    input [3:0] d;
    begin
        f1[0]=d[3];
        f1[1]=d[2];
        f1[2]=d[1];
        f1[3]=d[0];
    end
endfunction
assign c = rst_n ? f1(a) : 4'd0;
assign d = rst_n ? f1(b) : 4'd0;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Part two 组合逻辑

VL11 4位数值比较器电路

// VL11 4位数值比较器电路
// 直接比较不就行了
`timescale 1ns/1ns
module comparator_4(
    input [3:0] A,B,
    output reg  Y2,Y1,Y0
);
always @(*) begin Y2=(A>B);Y1=(A==B);Y0=(A<B); end
endmodule
// 根据题目要求,还是要用门级电路来做
module comparator_4(
    input [3:0] A,B,
    output wire Y2,Y1,Y0
);
reg Da3,Da2,Da1,Da0,De3,De2,De1,De0;
always @ (*) begin
    Da3=(A[3]&~B[3]);Da2=(A[2]&~B[2]);Da1=(A[1]&~B[1]);Da0=(A[0]&~B[0]);
    De3=~(A[3]^B[3]);De2=~(A[2]^B[2]);De1=~(A[1]^B[1]);De0=(~A[0]^B[0]);
end
assign Y2 = Da3 | De3&Da2 | De3&De2&Da1 | De3&De2&De1&Da0;
assign Y1 = De3&De2&De1&De0;
assign Y0 = ~Y2&~Y1;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

VL12 4bit超前进位加法器电路

// VL12 4bit超前进位加法器电路
// 用卡诺图化简,分别算出Sum和Cin
// Si=Ai^Bi^Ci 、 Ci+1=AiBi+(Ai+Bi)Ci
`timescale 1ns/1ns
module lca_4(
    input      [3:0] A_in,B_in,
    input            C_1,
    output reg       CO,
    output reg [3:0] S
);
reg [3:0] C;
always @ (*) begin
    C[0] = C_1;
    C[1] = A_in[0]&B_in[0] | (A_in[0]|B_in[0])&C[0];
    C[2] = A_in[1]&B_in[1] | (A_in[1]|B_in[1])&C[1];
    C[3] = A_in[2]&B_in[2] | (A_in[2]|B_in[2])&C[2];
    CO   = C[3];
    S    = A_in^B_in^C;
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

VL13 优先编码器电路1

// VL13 优先编码器电路1
// 使用casex语法按照给出的真值表输出对应的结果
`timescale 1ns/1ns
module encoder_0(
   input      [8:0] I_n   ,
   output reg [3:0] Y_n   
);
always @ (*)begin
    casex(I_n)
    9'b0xxx_xxxx_x: Y_n = 4'b0110;
    9'b10xx_xxxx_x: Y_n = 4'b0111;
    9'b110x_xxxx_x: Y_n = 4'b1000;
    9'b1110_xxxx_x: Y_n = 4'b1001;
    9'b1111_0xxx_x: Y_n = 4'b1010;
    9'b1111_10xx_x: Y_n = 4'b1011;
    9'b1111_110x_x: Y_n = 4'b1100;
    9'b1111_1110_x: Y_n = 4'b1101;
    9'b1111_1111_0: Y_n = 4'b1110;
    9'b1111_1111_1: Y_n = 4'b1111;
    default: Y_n = 4'b1111;
    endcase
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

VL14 用优先编码器①实现键盘编码电路
// VL14 用优先编码器①实现键盘编码电路
`timescale 1ns/1ns
module encoder(
   input      [8:0]         I_n   ,
   output reg [3:0]         Y_n   
);
// 这里都是取反,
always @(*)begin
   casex(I_n)
   9'b111111111 : Y_n = 4'b1111; // I=9'b000000000 Y=4'b0000 按键0
   9'b111111110 : Y_n = 4'b1110; // I=9'b000000001 Y=4'b0001 按键1
   9'b11111110x : Y_n = 4'b1101; // I=9'b00000001x Y=4'b0010 按键2
   9'b1111110xx : Y_n = 4'b1100; // I=9'b0000001xx Y=4'b0011 按键3
   9'b111110xxx : Y_n = 4'b1011; // I=9'b000001xxx Y=4'b0100 按键4
   9'b11110xxxx : Y_n = 4'b1010; // I=9'b00001xxxx Y=4'b0101 按键5
   9'b1110xxxxx : Y_n = 4'b1001; // I=9'b0001xxxxx Y=4'b0110 按键6
   9'b110xxxxxx : Y_n = 4'b1000; // I=9'b001xxxxxx Y=4'b0111 按键7
   9'b10xxxxxxx : Y_n = 4'b0111; // I=9'b01xxxxxxx Y=4'b1000 按键8
   9'b0xxxxxxxx : Y_n = 4'b0110; // I=9'b1xxxxxxxx Y=4'b1001 按键9
   default      : Y_n = 4'b1111; // I=9'bxxxxxxxxx Y=4'b0000 按键×
   endcase
end 
endmodule
// 这题怪就怪在输入的S_n有10位,意思就是把S_n[0]作为判断依据
// 从状态栏可见:S_n全为1时,L_n也全1,表示按键0按下
// 然后关于GS的状态,通过的答案是认为GS=1,代表没按键按下
// 这个也好理解,没按键按下只有一种情况,方便判断,拉高说明空闲了
// 意思就是当Y全为零,同时输入也全为零时,认为按键0,GS=0
// 意思就是当Y全为零,但是输入没有时,认为按键没按下,GS=1
module key_encoder(
      input       [9:0]         S_n   ,         
      output wire [3:0]         L     ,
      output wire               GS
);
wire [3:0] L_n; encoder encoder(S_n[9:1],L_n);
assign L  = ~L_n;
assign GS = ~(S_n[0]&L_n[0]&L_n[1]&L_n[2]&L_n[3]);
// assign GS = ~((S_n[0]==1'd1)&(L==4'd0));
endmodule


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

VL15 优先编码器Ⅰ

// VL15 优先编码器Ⅰ
// 没啥特别的,根据真值表来编
`timescale 1ns/1ns
module encoder_83(
   input       [7:0]      I   ,
   input                  EI  ,
   output reg  [2:0]      Y   ,
   output reg             GS  ,
   output reg             EO    
);
always @ (*)begin
    if(EI) 
        casex(I)
        8'b0000_0000: begin Y = 3'b000; GS = 1'b0; EO = 1'b1; end
        8'b0000_0001: begin Y = 3'b000; GS = 1'b1; EO = 1'b0; end// 1
        8'b0000_001x: begin Y = 3'b001; GS = 1'b1; EO = 1'b0; end// 2
        8'b0000_01xx: begin Y = 3'b010; GS = 1'b1; EO = 1'b0; end// 3
        8'b0000_1xxx: begin Y = 3'b011; GS = 1'b1; EO = 1'b0; end// 4
        8'b0001_xxxx: begin Y = 3'b100; GS = 1'b1; EO = 1'b0; end// 5
        8'b001x_xxxx: begin Y = 3'b101; GS = 1'b1; EO = 1'b0; end// 6
        8'b01xx_xxxx: begin Y = 3'b110; GS = 1'b1; EO = 1'b0; end// 7
        8'b1xxx_xxxx: begin Y = 3'b111; GS = 1'b1; EO = 1'b0; end// 8
        default     : begin Y = 3'b000; GS = 1'b0; EO = 1'b0; end
        endcase
    else              begin Y = 3'b000; GS = 1'b0; EO = 1'b0; end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

VL16 使用8线-3线优先编码器Ⅰ实现16线-4线优先编码器

// VL16 使用8线-3线优先编码器Ⅰ实现16线-4线优先编码器
// 两片级联的方式进行操作,通过对第二块的GS的值进行判断
// GS2=0:Y={0,Y1} GS=GS1 EO=EO1
// GS2=1:Y={1,Y2} GS=1   EO=0
`timescale 1ns/1ns
module encoder_83(
   input       [7:0] I   ,
   input             EI  ,
   output wire [2:0] Y   ,
   output wire       GS  ,
   output wire       EO    
);
assign Y[2] = EI & (I[7] | I[6] | I[5] | I[4]);
assign Y[1] = EI & (I[7] | I[6] | ~I[5]&~I[4]&I[3] | ~I[5]&~I[4]&I[2]);
assign Y[0] = EI & (I[7] | ~I[6]&I[5] | ~I[6]&~I[4]&I[3] | ~I[6]&~I[4]&~I[2]&I[1]);
assign EO = EI&~I[7]&~I[6]&~I[5]&~I[4]&~I[3]&~I[2]&~I[1]&~I[0];
assign GS = EI&(I[7] | I[6] | I[5] | I[4] | I[3] | I[2] | I[1] | I[0]);       
endmodule
module encoder_164(
   input      [15:0] A   ,
   input             EI  ,
   output wire [3:0] L   ,
   output wire       GS  ,
   output wire       EO    
);
wire       GS1,GS2,EO1,EO2;
wire [2:0] Y1,Y2;
encoder_83 encoder_1(A[7 :0],EI,Y1,GS1,EO1);
encoder_83 encoder_2(A[15:8],EI,Y2,GS2,EO2);
assign {L,GS,EO} = GS_2 ? {{1'b1,Y2},1'b1,1'b0} : {{1'b0,Y1},GS1,EO1};
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

VL17 用3-8译码器实现全减器

// VL17 用3-8译码器实现全减器
// 通过画卡诺图的方式先把全减器的逻辑表达式定下来:
// D=A^B^Ci 、 Co=~AB+(~A+B)Ci;
// 然后根据对应的ABC的值,查找对应的译码器输出值
module decoder_38(
   input            E,
   input      [2:0] A,
   output reg [7:0] Y  
);
always @(*)
    if(!E)             Y = 8'b00000000;             
    else if(A==3'b000) Y = 8'b00000001;             
    else if(A==3'b001) Y = 8'b00000010;             
    else if(A==3'b010) Y = 8'b00000100;             
    else if(A==3'b011) Y = 8'b00001000;             
    else if(A==3'b100) Y = 8'b00010000;
    else if(A==3'b101) Y = 8'b00100000;
    else if(A==3'b110) Y = 8'b01000000;
    else if(A==3'b111) Y = 8'b10000000;
    else               Y = 8'b00000000;      
endmodule

module decoder1(
   input  A,B,Ci,
   output D,Co         
);
wire  [7:0] Y;
decoder_38 decoder_38(1'b1,{A,B,Ci},Y);
assign D  = Y[1]|Y[2]|Y[4]|Y[7];
assign Co = Y[1]|Y[2]|Y[3]|Y[7];
endmodule


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

VL18 实现3-8译码器1 用基础门电路实现

// VL18 实现3-8译码器1 用基础门电路实现
// 根据图片来,输出由输入决定
`timescale 1ns/1ns
module decoder_38(
    input  E1_n,E2_n,E3,A0,A1,A2,
    output Y0_n,Y1_n,Y2_n,Y3_n,Y4_n,Y5_n,Y6_n,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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

VL19 使用3-8译码器1实现逻辑函数

// VL19 使用3-8译码器1实现逻辑函数
// 例化时注意顺序
// 根据逻辑表达式发现ABC=1,3,6,7时L为1,然后和对应的Y挂钩即可
`timescale 1ns/1ns
module decoder_38(
    input  E1_n,E2_n,E3,A0,A1,A2,
    output Y0_n,Y1_n,Y2_n,Y3_n,Y4_n,Y5_n,Y6_n,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,B,C,
   output L
);
wire Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7;
decoder_38 decoder_38(1'b0,1'b0,1'b1,C,B,A,Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7);
assign L = ~Y1 | ~Y3 | ~Y6 | ~Y7;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

VL20 数据选择器实现逻辑电路

// VL20 数据选择器实现逻辑电路
// 这题有意思的就在于对这个选择器的理解上
// 和前面题很像,先确定逻辑表达式,然后分配到输入输出
// L = A&B | A&~C | B&C 以A C作为输入 结果作为输出
`timescale 1ns/1ns
module data_sel(
   input S0,S1,D0,D1,D2,D3,
   output Y
);
assign Y = ~S1 & (~S0&D0 | S0&D1) | S1&(~S0&D2 | S0&D3);
endmodule
module sel_exp(
   input A,B,C,
   output L
);
data_sel data_sel(A,C,1'b0,1'b1,B,B,L);
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Part three 时序逻辑

VL21 根据状态转移表实现时序电路

// VL21 根据状态转移表实现时序电路
// 注意题目给的Y用的是wire型,是想要用组合逻辑来操作Y;
// 这里就比较麻烦,直接在状态机里一起走时序不是更好
// 但这应该是和几段式状态机相关吧,一段放时序,一段放组合
// 常规方案:一开始的思路,就画出状态转移说明
`timescale 1ns/1ns
module seq_circuit(
    input  A,clk,rst_n,
    output Y
);
reg [1:0] state;
always @ (posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        state <= 2'b0;
    end
    else begin
        case(state) 
        2'b00: if(A) state<=2'b11;else state<=2'b01;          
        2'b01: if(A) state<=2'b00;else state<=2'b10;          
        2'b10: if(A) state<=2'b01;else state<=2'b11;
        2'b11: if(A) state<=2'b10;else state<=2'b00;           
        endcase
    end
end
assign Y = (state==2'b11);
endmodule
// 方案二:题目是说用D触发器和必要逻辑门实现
// 通过画卡诺图方式化简来操作:(在下一题中比较明显)
`timescale 1ns/1ns
module seq_circuit(
    input  A,clk,rst_n,
    output Y
);
reg Q1,Q0;
always @ (posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        Q1 <= 1'b0;
        Q0 <= 1'b0;
    end
    else begin
        Q1 <= A^Q1^Q0;
        Q0 <= ~Q0;
    end
end
assign Y = Q1&Q0;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

VL22 根据状态转移图实现时序电路

// VL22 根据状态转移图实现时序电路
// 和上面那个题一样的画卡诺图来解
`timescale 1ns/1ns
module seq_circuit(
    input  C,clk,rst_n,
    output Y   
);
reg Q1,Q0;
always @ (posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        Q1 <= 1'b0;
        Q0 <= 1'b0;
    end
    else begin
        Q1 <= ~C&Q0 |  Q1&Q0 | C&Q1 ;
        Q0 <= ~C&Q0 | ~Q1&Q0 | C&~Q1;
    end
end
assign Y = Q1&Q0|C&Q1;
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

VL23 ROM的简单实现

//VL23 ROM的简单实现
// 这一题在这边关于这个变量的申明特别有意思!!
`timescale 1ns/1ns
module rom(
    input             clk,rst_n,
    input       [7:0] addr,
    output wire [3:0] data
);
reg [3:0] rom[7:0];
always @ (posedge clk or negedge rst_n) begin
    rom[0] <= 4'd0 ;
    rom[1] <= 4'd2 ;
    rom[2] <= 4'd4 ;
    rom[3] <= 4'd6 ;
    rom[4] <= 4'd8 ;
    rom[5] <= 4'd10;
    rom[6] <= 4'd12;
    rom[7] <= 4'd14;
end
assign data = rom[addr];
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

VL24 边沿检测

// VL24 边沿检测
// 通过打一拍的方式获得delay,通过取反相与的方式找到边沿
// 不知道为啥不能直接赋值,说什么会出现不定态,很迷惑??????
`timescale 1ns/1ns
module edge_detect(
    input      clk,rst_n,a,
    output reg rise,down
);
reg delay;
always @ (posedge clk) delay <= a;
always @ (posedge clk or negedge rst_n) begin
    if(~rst_n)        begin rise <= 1'b0; down <= 1'b0; end
    else if(~delay&a) begin rise <= 1'b1; down <= 1'b0; end
    else if(~a&delay) begin rise <= 1'b0; down <= 1'b1; end
    else              begin rise <= 1'b0; down <= 1'b0; end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/583225
推荐阅读
  

闽ICP备14008679号