https://github.com/zsylov/verliog-study/blob/master/2019.5.6%E8%AE%A1%E6%95%B0%E5%99%A8.md
用verilog实现一个4bit二进制计数器。
====
a) 异步复位
b) 同步复位
input clk, rst_n;
output [3:0] o_cnt;
```verilog
`timescale 1ns/1ps
module Syn_counter(
input clk,rst_n,
output[3:0] o_cnt
);
reg [3:0] o_cnt_r;
always @ (posedge clk)
if(!rst_n)
o_cnt_r <= 4'b0000;
else if(o_cnt_r == 4'b1111) o_cnt_r <= 4'b0000;
else
o_cnt_r <= o_cnt_r + 1'b1;
assign o_cnt =o_cnt_r;
endmodule
`timescale 1ns/1ps
module aSyn_counter(
input clk,rst_n,
output[3:0] o_cnt
);
reg [3:0] o_cnt_r;
always @ (posedge clk or negedge rst_n)
if(!rst_n)
o_cnt_r <= 4'b0000;
else if(o_cnt_r == 4'b1111) o_cnt_r <= 4'b0000;
else
o_cnt_r <= o_cnt_r + 1'b1;
assign o_cnt =o_cnt_r;
endmodulele
```
```verilog
`timescale 1ns/1ps
module Syn_counter(
input clk,rst_n,
output[3:0] o_cnt
);
reg [3:0] o_cnt_r;
always @ (posedge clk)
if(!rst_n)
o_cnt_r <= 4'b0000;
else if(o_cnt_r == 4'b1111) o_cnt_r <= 4'b0000;
else
o_cnt_r <= o_cnt_r + 1'b1;
assign o_cnt =o_cnt_r;
endmodule
// Code your testbench here
// or browse Examples
`timescale 1ns/1ps
module test_Syncounter();
reg clk;
reg rst_n;
wire [3:0] o_cnt;
initial
begin
$dumpfile("t.vcd");
$dumpvars(1);
clk =0;
rst_n= 0;
#100
rst_n=1;
end
always #10 clk = ~clk;
Syn_counter Syn_counter_inst(clk,rst_n,o_cnt);
endmodule
```
![仿真](https://github.com/zsylov/verliog-study/blob/master/%E2%80%9C/%E2%80%9D/Syn.PNG)
2.用verilog实现4bit约翰逊(Johnson)计数器
====
```verilog
`timescale 1ns/1ps
module Joh_counter(
input clk,
input rst_n,
output[3:0] o_cnt
);
reg [3:0] counter;
always @(posedge clk , negedge rst_n)
if(!rst_n)
counter <= 4'b0000;
else if(counter[0] == 1)
counter <= {1'b0,counter[3:1]};
else
counter <= {1'b1,counter[3:1]};
assign o_cnt =counter;
endmodule
testbench
// Code your testbench here
// or browse Examples
`timescale 1ns/1ps
module test_joh();
reg clk;
reg rst_n;
wire [3:0]o_cnt;
initial
begin
$dumpfile("d.vcd");
$dumpvars(1);
clk=0;
rst_n=0;
#40
rst_n =1;
end
always #10 clk=~clk;
Joh_counter Joh_counter_inst(clk,rst_n,o_cnt);
endmodule
````
![仿真](https://github.com/zsylov/verliog-study/blob/master/%E2%80%9C/%E2%80%9D/Johno.PNG)
3.用verilog实现4bit环形计数器:复位有效时输出0001,复位释放后依次输出0010,0100,1000,0001,0010...
====
```verilog
// Code your design here
`timescale 1ns/1ps
module cy_counter(
input clk,
input rst_n,
output[3:0] o_cnt
);
reg [3:0] counter;
always @(posedge clk , negedge rst_n)
if(!rst_n)
counter <= 4'b0001;
else if(counter[3] == 1)
counter <= 4'b0001;
else
counter <= {counter[2:0],1'b0};
assign o_cnt =counter;
endmodule
```
![仿真](https://github.com/zsylov/verliog-study/blob/master/cy.PNG)
4.比较一下以上三种计数器的特点。
===
1.4Bit二进制计数器有16个状态,johnson计数器利用n位触发器来表示2n个状态的计数器。约翰逊计数器的状态表中,相邻两组代码只可能有一位二进制代码不同,故在计数过程中不会产生错误的译码信号。环形计数器利用n位触发器仅可表示n个状态。
5.记录1,2,3题目使用的工具,操作步骤,以及出现的错误和提示信息。
===
使用WWW.edaplayground.com进行功能仿真,由于三个计数器结构差不多,尤其环形计数器与johnoson计数器,在写testbench时忘记改例化模块导致错误,改正后没出现其他古怪的问题。