Chinaunix首页 | 论坛 | 博客
  • 博客访问: 360376
  • 博文数量: 112
  • 博客积分: 5245
  • 博客等级: 大校
  • 技术积分: 1120
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-07 09:20
个人简介

静下来,定好方向,好好干。

文章分类
文章存档

2017年(1)

2012年(1)

2011年(5)

2010年(6)

2009年(16)

2008年(59)

2007年(24)

我的朋友

分类:

2009-07-16 22:56:14

近期学习了一些Verilog知识,以下是部分有代表性的Verilog例程:

普通触发器的设计
module dff(q,data,clk);
output q;
input data, clk;
reg q;
always @(posedge clk)
begin
q=data;
end
endmodule

同步清零、置位触发器的设计
module dff_rs_syn(q,data,set,clr,clk);
output q;
input data, set, clr, clk;
reg q;
always @(posedge clk)
begin
if(!clr)
q=0;
else if(!set)
q=1;
else
q=data;
end
endmodule

异步清零、置位触发器的设计
module dff_rs_asyn(q,data,set,clr,clk);
output q;
input data, set, clr, clk;
reg q;
always @(clror set or posedge clk)
begin
if(!clr)
q=0;
else if(!set)
q=1;
else
q=data;
end
endmodule

移位寄存器的设计
module shift(data_out, data_in, clr, clk);
output [7:0] data_out;
input data_in, clr, clk;
reg [7:0] data_out;
always @(posedge clk)
begin
if(!clr)
data_out=8’b0;
else
begin
data_out=data_out<<1;
data_out[0]=data_in
end
end
endmodule

module orand(OUT,A,B,C,D,E);
input A,B,C,D,E;
output OUT;
//描述方法一:基本元件调用方式
or (or1, A, B);
or (or2, C, D);
and (OUT, or1, or2, E);
endmodule

module orand(OUT,A,B,C,D,E);
input A,B,C,D,E;
output OUT;
//描述方法二:assign连续赋值语句方式
assign OUT=E&(A|B)&(C|D);
endmodule

module orand(OUT,A,B,C,D,E);
input A,B,C,D,E;
output OUT;
//描述方法三:过程赋值语句方式
reg OUT;
always @(A or B or C or D or E)
begin
if(E)
OUT=(A|B)&(C|D);
else
OUT=0;
end
endmodule

module orand(OUT,A,B,C,D,E);
input A,B,C,D,E;
output OUT;
//描述方法四:过程连续赋值语句方式
reg OUT;
always @(E)
begin
if(E)
assign OUT=(A|B)&(C|D);
else
assign OUT=0;
end
endmodule

module dlatch(out, in, enable);
input [7:0] in;
output [7:0] out;
input enable;
//描述方法一:过程赋值语句描述方式
reg [7:0] out;
always @(in or enable)
begin
if(enable)
out=in;
end
endmodule88outinen

module dlatch(out, in, enable);
input [7:0] in;
output [7:0] out;
input enable;
//描述方法二:过程连线赋值语句描述方式
reg [7:0] out;
always @(enable)
begin
if(enable)
assign out=in;
else
deassignout;
end
endmodule88outinen

module mux(out, a, b, c, d, sel);
output [3:0] out;
input [3:0] a, b, c, d;
input [1:0] sel;
reg [3:0] out;
always @(a or b or c or d or sel)
begin
case(sel)
2’b00:out=a;
2’b01:out=b;
2’b10: out=c;
2’b11:out=d;
default:out=4’bx;
endcase
end
endmodule244abcdselout

交通灯控制器设计
`define HIGH_PASS 4'b0000
`define FOOT_PASS 4'b0001
`define HIGH_YELLOW 4'b0010
`define ALL_STOP 4'b0011
`define TH 90
`define TF 20
`define TY 5
`define TA 10

module trafficlight(clk,reset,req,
high_red,high_yellow,high_green,foot_red,foot_green);
input clk;
input reset;
input req;
output
high_red,high_yellow,high_green,foot_red,foot_green;
reg high_red,high_yellow,high_green,foot_red,foot_green;
reg [3:0] state; // 状态
reg [15:0] counter; // 计时器
reg req_r; // 按钮寄存器

always @(posedge clk)
    begin
    if (reset)
        begin // 复位,
        state <= `HIGH_PASS; // 初始状态为公路通行
        counter <= 0; // 计时器清0
        req_r<=0;
        end
    else
        begin
        if (req) req_r=1;  //阻塞式赋值,下文中req_r本周期生效
        //if (req) req_r<=1;  //非阻塞式赋值,下文中req_r要下个周期才生效
        counter <= counter + 1; // 计时器递增
            case (state) // 状态转移控制
            `HIGH_PASS: // 公路通行状态
                // if (req) begin 修改为
                if (req_r && counter >= `TH) begin // 公路通行时间超过TH
                // 且有行人申请
                state <= `HIGH_YELLOW; // 状态转移至公路黄灯
                counter <= 0; // 计时器清0
                end
            `FOOT_PASS: // 人行道通行状态
                if (counter == `TF) begin //人行道通行时间等于TF
                state <= `ALL_STOP; // 状态转移至双向红灯
                counter <= 0; // 计时器清0
                req_r <= 0; // 按钮寄存器清0
                end
            ` HIGH_YELLOW : // 公路黄灯状态
                if (counter == `TY) begin // 黄灯时间等于TY
                state <= `FOOT_PASS; // 状态转移至人行道通行
                counter <= 0; // 计时器清0
                end
            ` ALL_STOP : // 双向红灯状态
                if (counter == `TA) begin // 双向红灯时间等于TA
                state <= `HIGH_PASS; // 状态转移至公路通行
                counter <= 0; // 计时器清0
                end
            endcase
        end
    end

always @(state) // 设置各个状态的控制输出
    begin
    {high_red,high_yellow,high_green,foot_red,foot_green} = 0;
        case(state)
        // 公路通行状态,公路绿灯,人行道红灯
        `HIGH_PASS: begin high_green = 1;foot_red = 1;end
        //人行道通行状态,公路红灯,人行道绿灯
        `FOOT_PASS: begin foot_green = 1;high_red = 1;end
        // 公路黄灯状态,公路黄灯,人行道红灯
        `HIGH_YELLOW:begin high_yellow = 1;foot_red = 1; end
        // 双向红灯状态,公路红灯,人行道红灯
        `ALL_STOP: begin high_red = 1; foot_red = 1; end
        endcase
    end
endmodule



module testbench;

reg clk,reset,req;
integer count; // clk 计数器

trafficlight ut(clk,reset,req,
high_red,high_yellow,high_green,
foot_red,foot_green);

initial
    begin
    clk = 1'bx;
    reset = 1; // reset 高有效
    # 5 clk = 0;
    # 45 reset <= #225 1'b0; // reset 置0开始正常工作

    forever #50 clk = ~clk; //产生工作时钟,周期100
    end

initial count <= 0; // clk 计数清0

always @(posedge clk)
    begin
    count <= count + 1; // clk 计数递增
        case (count)
        100, // 行人较少
        200,
        500, // 以下行人数量增多间隔变小
        540,
        580,
        620,
        660, // :req <= 1;
        700:req <= 1;
        1000:$finish;
        default: req <= 0;
        endcase
    end

initial $monitor($time,"%d, %d, req:%b, h_r:%b, h_y:%b, h_g:%b, f_r:%b, f_g:%b",
count, ut.counter, req, high_red,high_yellow,high_green,foot_red,foot_green );

endmodule

--------------------------------------------------------------------------------
task 任务名;
端口与类型说明;
局部变量说明;
块语句
endtask

function <位宽说明>函数名;
输入端口与类型说明;
局部变量说明;
块语句
endfunction

函数与任务区别:
1.任务和函数的定义和引用都位于模块的内部,而不是一个独立的模块。
2.函数不能调用任务,而任务可以调用任何其它的任务或函数。
3.任务可以没有输入变量或有任意类型的I/O变量,而函数允许有输入变量且至少有一个,输出则由函数名自身担当。
4.函数通过函数名返回一个值,任务名本身没有值的意义,只是实现某种操作,传值通过I/O端口实现。
5.任务和函数的定义中,内部都没有过程块。
6.函数还可以出现在连续赋值语句assign的右端表达式中。
阅读(814) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~