HDLBits — Verilog Practice
HDLbits网址:https://hdlbits.01xz.net/wiki/Main_Page
Getting Started
Getting Started
module top_module( output one );
// Insert your code here
assign one = 1'b1;
endmodule
Output Zero
module top_module(
output zero
);// Module body starts after semicolon(分号)
zero = 0;
endmodule
Verilog Language
Basics
Simple wire
module top_module( input in, output out );
assign out = in; // wires are directional(有方向性)
endmodule
Four wires
module top_module(
input a,b,c,
output w,x,y,z );
assign w = a;
assign x = b;
assign y = b;
assign z = c;
// If we're certain about the width of each signal, using
// the concatenation operator is equivalent and shorter:
// assign {w,x,y,z} = {a,b,b,c};
endmodule
Inverter
module top_module(
input in,
output out
);
assign out = ~in;
endmodule
AND gate
module top_module(
input a,
input b,
output out );
assign out = a & b;
endmodule
NOR gate
module top_module(
input a,
input b,
output out );
assign out = ~(a|b); // 或非
endmodule
XNOR gate
module top_module(
input a,
input b,
output out );
assign out = a ^~ b; // out = ~(a^b) 同或 = 异或的非
endmodule
Declaring wires
module top_module (
input a,
input b,
input c,
input d,
output out,
output out_n );
wire w1, w2; // **Declare two wires** (named w1 and w2)
assign w1 = a & b; // First AND gate
assign w2 = c & d; // Second AND gate
assign out = w1 | w2; // OR gate: Feeds both 'out' and the NOT gate
assign out_n = ~out; // NOT gate
endmodule
7458 chip
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p2y = (p2a & p2b)|(p2c & p2d);
assign p1y = (p1a & p1b & p1c)|(p1d & p1e & p1f);
****// 这里并没有像上一节声明中间线网
endmodule
Vectors
Vectors
module top_module(
input [2:0] vec,
output [2:0] outv,
output o2,
output o1,
output o0
);
assign outv = vec;
// This is ok too: assign {o2, o1, o0} = vec;
assign o0 = vec[0];
assign o1 = vec[1];
assign o2 = vec[2];
endmodule
Vectors in more detail
/*
Build a combinational circuit that splits an input half-word (16 bits, [15:0] ) into lower [7:0] and upper [15:8] bytes.
*/
module top_module (
input [15:0] in,
output [7:0] out_hi,
output [7:0] out_lo
);
assign out_hi = in[15:8];
assign out_lo = in[7:0];
// Concatenation operator also works: assign {out_hi, out_lo} = in;
endmodule
Vector part select
/*
A 32-bit vector can be viewed as containing 4 bytes (bits [31:24], [23:16], etc.). Build a circuit that will reverse the byte ordering of the 4-byte word.
AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa
*/
module top_module (
input [31:0] in,
output [31:0] out
);
assign out[31:24] = in[ 7: 0];
assign out[23:16] = in[15: 8];
assign out[15: 8] = in[23:16];
assign out[ 7: 0] = in[31:24];
// or you can write this:assign out ={in[7:0],in[15:8],in[23:16],in[31:24]};
endmodule
Bitwise operators
module top_module(
input [2:0] a,
input [2:0] b,
output [2:0] out_or_bitwise,
output out_or_logical,
output [5:0] out_not
);
assign out_or_bitwise = a | b;
assign out_or_logical = a || b;
assign out_not[2:0] = ~a; // Part-select on left side is o.
assign out_not[5:3] = ~b; //Assigning to [5:3] does not conflict with [2:0]
endmodule
Four-input gate
/*
Build a combinational circuit with four inputs, in[3:0].
There are 3 outputs:
out_and: output of a 4-input AND gate.
out_or: output of a 4-input OR gate.
out_xor: output of a 4-input XOR gate.
*/
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
//also you can do this:assign out_and = in[3]&in[2]&in[1]&in[0];
endmodule
Vector concatenation operator
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );//
// assign { ... } = { ... };
assign { w, x, y,z } = { a, b, c, d, e, f, {2{1'b1}} };
endmodule
Vector reverasal 1
// Given an 8-bit input vector [7:0], reverse its bit ordering.
module top_module (
input [7:0] in,
output [7:0] out
);
assign {out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]} = in;
endmodule
-----------------------------------------------------------------------------
module top_module (
input [7:0] in,
output [7:0] out
);
integer i;
always @(*) begin
for (i=0; i<8; i++)
// int is a SystemVerilog type. Use integer for pure Verilog.
out[i] = in[8-i-1];
end
endmodule
-----------------------------------------------------------------------------
module top_module (
input [7:0] in,
output [7:0] out
);
generate
genvar i;
for (i=0; i<8; i = i+1) begin: my_block_name
assign out[i] = in[8-i-1];
end
endgenerate
endmodule
// ***Todo* 后续还会提到,没理解不要紧**
Replication operator
/*
Build a circuit that sign-extends an 8-bit number to 32 bits. This requires a concatenation of 24 copies of the sign bit (i.e., replicate bit[7] 24 times) followed by the 8-bit number itself.
*/
**module top_module (
input [7:0] in,
output [31:0] out
);
// Concatenate two things together:
// 1: {in[7]} repeated 24 times (24 bits)
// 2: in[7:0] (8 bits)
assign out = { {24{in[7]}}, in };
endmodule**
More replication
module top_module (
input a, b, c, d, e,
output [24:0] out
);
wire [24:0] top, bottom;
assign top = { {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} };
assign bottom = {5{a,b,c,d,e}};
assign out = ~top ^ bottom; // Bitwise XNOR
// This could be done on one line:
// assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} } ^ {5{a,b,c,d,e}};
endmodule
Modules : Hierarchy
Modules
/*
module mod_a ( input in1, input in2, output out );
// Module body
endmodule
*/
module top_module (
input a,
input b,
output out
);
// Create an instance of "mod_a" named "inst1", and connect ports by name:
mod_a inst1 (
.in1(a), // Port"in1"connects to wire "a"
.in2(b), // Port "in2" connects to wire "b"
.out(out) // Port "out" connects to wire "out"
// (Note: mod_a's port "out" is not related to top_module's wire "out".
// It is simply coincidence that they have the same name)
);
endmodule
Connecting ports by position
//You are given the following module:
//module mod_a ( output, output, input, input, input, input );
//本题中mod_a这个模块的端口名未标明,只能按照位置的顺序来连接
//写文档的时候这样只表注输入输出端口而没有名字是不规范的
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a instance1(out1,out2,a,b,c,d);
endmodule
Connecting ports by name
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a name(
.in1(a),
.in2(b),
.in3(c),
.in4(d),
.out1(out1),
.out2(out2),
);
endmodule
Three modules
module top_module ( input clk, input d, output q );
wire mid1;
wire mid2;
my_dff inst1(
.clk(clk),
.d(d),
.q(mid1)
);
my_dff inst2(
.clk(clk),
.d(mid1),
.q(mid2)
);
my_dff inst3(
.clk(clk),
.d(mid2),
.q(q)
);
endmodule
-----------------------------------------------------------------------------
**Web** **Solution**:
module top_module (
input clk,
input d,
output q
);
wire a, b; // Create two wires. I called them a and b.
// Create three instances of my_dff, with three different instance names (d1, d2, and d3).
// Connect ports by position: ( input clk, input d, output q)
my_dff d1 ( clk, d, a );
my_dff d2 ( clk, a, b );
my_dff d3 ( clk, b, q );
endmodule
相当于三级延时 一次一个clk
D触发器 ( D Flip-flop ):
D触发器有一个输入、一个输出和一个时脉输入,当时脉由0转为1时,输出的值会和输入的值相等。S为1时强迫Q值为1,R为1时强迫Q值为0。
Modules and vectors
//module my_dff8 ( input clk, input [7:0] d, output [7:0] q );
//my first answer
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] a,b,c;
my_dff8 d1(clk,d,a);
my_dff8 d2(clk,a,b);
my_dff8 d3(clk,b,c);
always@(*)
if(sel==0) begin q <= d;end
else if(sel==1) begin q <= a;end
else if(sel==2) begin q <= b;end
else if(sel==3) begin q <= c;end
endmodule
-----------------------------------------------------------------------------
**Web** **Solution**:
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output reg [7:0] q
);
wire [7:0] o1, o2, o3; // output of each my_dff8
// Instantiate three my_dff8s
my_dff8 d1 ( clk, d, o1 );
my_dff8 d2 ( clk, o1, o2 );
my_dff8 d3 ( clk, o2, o3 );
// This is one way to make a 4-to-1 multiplexer
always @(*) // Combinational always block
case(sel)
2'h0: q = d;
2'h1: q = o1;
2'h2: q = o2;
2'h3: q = o3;
endcase
endmodule
Adder 1
/*
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
*/
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] a1,a2,b1,b2,sum1,sum2;
wire [ 0:0]cout;
assign a1 = a[15: 0];
assign a2 = a[31:16];
assign b1 = b[15: 0];
assign b2 = b[31:16];
add16 add_low(
.a(a1),
.b(b1),
.cin(),
.sum(sum1),
.cout(cout)
);
add16 add_hig(
.a(a2),
.b(b2),
.cin(cout),
.sum(sum2),
.cout()
);
assign sum[31:16] = sum2;
assign sum[15: 0] = sum1;
endmodule
-----------------------------------------------------------------------------
//**Web Solution:
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout1;
//线网信号可以是截位的
add16 add1(a[15: 0],b[15: 0], 1'b0,sum[15: 0],cout1);
add16 add2(a[31:16],b[31:16],cout1,sum[31:16],);//注意这里进位信号没有线网所连接
endmodule**
Adder 2
//行波进位加法器(RCA: Ripple-Carry Adder)
//缺点 进位输出延迟
//add16 web里提供 其中例化了16个add1
//module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout1;
add16 add1(a[15: 0],b[15: 0], 1'b0,sum[15: 0],cout1);
add16 add2(a[31:16],b[31:16],cout1,sum[31:16],);
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
// Full adder module here
assign sum = a^b^cin; //模二加法=异或
assign cout = a&b | a&cin | b&cin; //单凡三个数中有两个一则进位
endmodule
Carry-select adder
// module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout1;
wire [15:0] sum1,sum2;
add16 add1(a[15: 0],b[15: 0],1'b0,sum[15: 0],cout1);
add16 add2(a[31:16],b[31:16],1'b0,sum1);
add16 add3(a[31:16],b[31:16],1'b1,sum2);
always @(*)
case(cout1)
1'b0: sum[31:16] = sum1;
1'b1: sum[31:16] = sum2;
endcase
endmodule
-----------------------------------------------------------------------------
// Web Solution
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire carry;
wire [31:16] sum0;
wire [31:16] sum1;
add16 al(a[15:0],b[15:0],1'b0,sum[15:0],carry);
add16 ah0(a[31:16],b[31:16],1'b0,sum0[31:16],);
add16 ah1(a[31:16],b[31:16],1'b1,sum1[31:16],);
assign sum[31:16] = carry?sum1:sum0; // 二选一
endmodule
Adder-subtractor
// 减去一个数等于奖赏这个数的补码
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
//module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
wire [31:0] c;
wire cout;
assign c = b^{32{sub}};
add16 d1(a[15: 0],c[15: 0], sub,sum[15: 0],cout);
add16 d2(a[31:16],c[31:16],cout,sum[31:16],);
endmodule
Procedures
More Verilog Featureas
Circuits
Verification : Reading Simulations
Verification : Writing Testbenches
内容来源于网络如有侵权请私信删除
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!