Verilog课程设计

Verilog课程设计
Verilog课程设计

一.实验目的

(1)学习RISC_CPU的基本结构和原理;

(2)了解Verilog HDL仿真和综合工具的潜力;

(3)展示Verilog设计方法对软/硬件联合设计和验证的意义;

(4)学习并掌握一些常用的Verilog语法和验证方法。

二.实验原理

CPU即中央处理单元的英文缩写,它是计算机的核心部件。计算机进行信息处理可分为两个步骤:

(1)将数据和程序(即指令序列)输入计算机的存储器中。

(2)从第一条指令的地址起开始执行该程序,得到所需结果,结束运行。CPU的作用是协调并控制计算机的各个部件并执行程序的指令序列,使其有条不紊地进行。因此它必须具有以下基本功能。

①取指令——当程序忆在存储器中时,首先根据程序入口地址取出一条程序,为此要发出指令地址及控制信号。

②分析指令——即指令译码,这是对当前取得的指令进行分析,指出它要求什么操作,并产生相应的操作控制命令。

③执行指令——根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器、存储器及输入/输出设备的执行,实现每条指令的功能,其中包括对运算结果的处理以及下条指令地址的形成。

将CPU的功能进一步细化,可概括如下:

(1)能对指令进行译码并执行规定的动作;

(2)可以进行算术和逻辑运算;

(3)能与存储器和外设交换数据;

(4)提供整个系统所需要的控制。

尽管各种CPU的性能指标和结构细节各不相同,但它们所能完成的基本功能相同。由功能分析,可知任何一种CPU内部结构至少应包含下面这些部件:(1)算术逻辑运算部件(ALU);

(2)累加器;

(3)程序计数器;

(4)指令寄存器和译码器;

(5)时序和控制部件。

三.实验内容

通过我们自己动手,设计出一个CPU的软核和固核。这个CPU是一个简化的专门为教学目的而设计的RISC_CPU。在设计中我们不但关心CPU总体设计的合理性,而且还使得构成这个RISC_CPU的每一个模块不仅是可仿真的也都可以综合成门级网表。因而从物理意义上说,这也是一个能真正通过具体电路结构而实现的CPU。为了能在这个虚拟的CPU上运行较为复杂的程序并进行仿真,把寻址空间规定为8K(即13们地址线)字节。

四.实验代码

1.源代码

//----------------------------------clk_gen.v------------------------------

`timescale 1ns/1ns //时间单位1ns,时间单位1ns

module clk_gen(clk,reset,fetch,alu_ena); //模块名clk_gen,参数列表(clk,reset,fetch,alu_ena)input clk,reset; //输入clk,reset

output fetch,alu_ena; //输出fetch,alu_ena

wire clk,reset; //wire型变量clk,reset

reg fetch,alu_ena; //reg寄存器型变量fetch,alu_ena

reg[7:0]state; //reg寄存器型变量8位的state

parameter

S1=8'b00000001,S2=8'b00000010,S3=8'b00000100,S4=8'b00001000,S5=8'b00010000,S6=8'b001 00000,S7=8'b01000000,S8=8'b10000000,idle=8'b00000000;

//参数型定义8位二进制常量s1,s2,s3,s4,s5,s6,s7,s8,idle

always@(posedge clk) //always块时钟触发

if(reset) //如果reset为真

begin //执行begin,and顺序块

fetch<=0; //fetch非阻塞赋值赋为0

alu_ena<=0; //alu_ena非阻塞赋值赋为0

state<=idle; //idle非阻塞赋值给state

end

else //reset为假执行下面begin语句

begin

case(state) //case表达式(state)

S1:begin

alu_ena<=1; //alu_ena非阻塞赋值赋为1

state<=S2; //state非阻塞赋值赋为S2

end

S2:begin

alu_ena<=0; //alu_ena非阻塞赋值赋为0

state<=S3; //state非阻塞赋值赋为S3

end

alu_ena<=1; //alu_ena非阻塞赋值赋为1

state<=S4; //state非阻塞赋值赋为S4

end

S4:begin

state<=S5; //state非阻塞赋值赋为S5

end

S5:state<=S6; //state非阻塞赋值赋为S6

S6:state<=S7; //state非阻塞赋值赋为S7

S7:begin

fetch<=0; //fetch非阻塞赋值赋为0

state<=S8; //state非阻塞赋值赋为S8

end

S8:begin

state<=S1; //state非阻塞赋值赋为S1

end

idle:state<=S1; //idle_state非阻塞赋值赋为S1

default:state<=idle; //default_state非阻塞赋值赋为idle

endcase

end

endmodule //结束module模块

//----------------------------register.v-----------------------------

`timescale 1ns/1ns //时间单位1ns,时间精度1ns

module register(opc_iraddr,data,ena,clk,rst); //模块名register参数链表(变量名)output[15:0] opc_iraddr; //输出16位的opc_iraddr

input[7:0]data; //输入8位的data

input ena,clk,rst; //输入ena,clk,rst

reg[15:0]opc_iraddr; //定义16位的寄存器型变量opc_iraddr

reg state; //定义寄存器型变量state

always@(posedge clk) //always时钟触发

begin

if(rst) //判断rst是否为真

begin

opc_iraddr<=16'b0000_0000_0000_0000; //opc_iraddr非阻塞赋值赋为16位的二进制数

state<=1'b0; //state非阻塞赋值赋为1位的二进制数

end

else

begin

if(ena) //如果加载指令寄存器信号load_ir

begin //分两个时钟,每次8位加载指令寄存器

casex(state) //先高字节后低字节

opc_iraddr[15:8]<=data; //后8位的opc_iraddr非阻塞赋值赋为data

state<=1; //state非阻塞赋值赋为1

end

1'b1:begin

opc_iraddr[7:0]<=data; //8位的opc_iraddr非阻塞赋值赋为data

state<=0; //state非阻塞赋值赋为0

end

default:begin

opc_iraddr[15:0]<=16'bxxxxxxxxxxxxxxxx; //16位的opc_iraddr非阻塞赋值赋为16位的二进制数

state<=1'bx; //state非阻塞赋值赋为1位的二进制数

end

endcase

end

else

state<=1'b0; //state非阻塞赋值赋为1位的二进制数

end

end

Endmodule

--------------------------------accum.v------------------------------

module accum(accum,data,ena,clk,rst); //模块名accum参数列表()

output[7:0] accum; //输出8位的accum

input[7:0]data; //输入8位的data

input ena,clk,rst; //输入为ena,clk,rst

reg[7:0]accum; //定义一个寄存器型变量accum

always@(posedge clk) //always时钟触发

begin

if(rst) //判断rst是否为真

accum<=8'b0000_0000; //Reset

else

if(ena)//CPU状态控制器发出load_acc信号

accum<=data; //Aaccumulate

end

Endmodule

--------------------------alu.v------------------------------

`timescale 1ns/1ns //时间单位1ns,时间精度1ns

module alu(clk,alu_out,zero,data,accum,alu_ena,opcode); //模块名alu参数列表()output[7:0]data,accum,alu_out,zero; //输出8位的data,accum,alu_out,zero input[2:0]opcode; //输入3位的opcode

input alu_ena,clk; //输入为alu_ena,clk

reg[7:0]alu_out; //定义一个8位的寄存器型变量alu_out

parameter HLT =3'b000, //参数定义一个常量HLT阻塞赋值为3位的二进制数0 SKZ =3'b001, //SKZ阻塞赋值为3位的二进制数1

ADD =3'b010, //ADD阻塞赋值为3位的二进制数2

ANDD=3'b011, //ANDD阻塞赋值为3位的二进制数3

XORR=3'b100, //XORR阻塞赋值为3位的二进制数4

LDA =3'B101, //LDA阻塞赋值为3位的二进制数5

STO =3'b110, //STO阻塞赋值为3位的二进制数6

JMP =3'b111; //JMP阻塞赋值为3位的二进制数7

assign zero=!accum; //

always@(posedge clk) //always时钟触发模块

if(alu_ena) //判断alu_ena是否为真

begin //操作码来自指令寄存器的输出opc_iaddr(15..0)的低三位

casex(opcode) //casex(变量名)

HLT:alu_out<=accum;

SKZ:alu_out<=accum;

ADD:alu_out<=data+accum;

ANDD:alu_out<=data&accum;

XORR:alu_out<=data^accum;

LDA:alu_out<=data;

STO:alu_out<=accum;

JMP:alu_out<=8'bxxxx_xxxx; //以上都不是则alu_out非阻塞赋值赋为8位的二进制数

endcase

end

Endmodule

-------------------------------------datactl.v----------------------------

module datactl(data,in,data_ena); //模块名datactl参数列表()

output[7:0]data; //输出8位的data

input[7:0]in; //输入8位的in

input data_ena; //输入data_ena

assign data=(data_ena)?in:8'bzzzz_zzzz; //data_ena是否为1,如果为1就把in 赋给data,为0则把高阻态赋给data

Endmodule

---------------------------adr.v----------------------------------

module adr(addr,fetch,ir_addr,pc_addr); //模块名adr参数列表()output[12:0]addr; //输出13位的addr

input[12:0]ir_addr,pc_addr; //输入13位的ir_addr,pc_addr

input fetch; //输入fetch

assign addr=fetch? pc_addr:ir_addr; //fetch是否为1,如果为1就把pc_addr 赋给addr,为0则把ir_addr赋给addr

Endmodule

-----------------------counter.v--------------------------------

module counter(pc_addr,ir_addr,load,clock,rst); //模块名counter参数列表()output[12:0]pc_addr; //输出13位的pc_addr

input[12:0]ir_addr; //输入13位的ir_addr

input load,clock,rst; //输入load,clock,rst

reg[12:0]pc_addr; //定义13位的寄存器型变量pc_addr

always@(posedge clock or posedge rst) // always时钟或复位触发模块begin

if(rst)

pc_addr<=13'b0_0000_0000_0000; //Reset

else

if(load)

pc_addr<=ir_addr; //Load

else

pc_addr<=pc_addr+1; //把pc_addr+1非阻塞赋值给pc_addr end

Endmodule

-------------------------machinectl.v-----------------------

`timescale 1ns/1ns

module machinectl(ena,fetch,rst,clk); //machinectl模块输入输出列表

input fetch,rst,clk; //输入为fetch,rst,clk

output ena; //输出ena

reg ena; //定义寄存器型变量ena

reg state; //定义寄存器型变量state

always@(posedge clk) //上升沿触发

begin

if(rst) //如果rst为真

begin

ena<=0; //把0非阻塞赋值给ena

end //结束

else //否则

if(fetch) //如果fetch为真

begin

ena<=1; //把1非阻塞赋值给ena

end //结束

end //结束

endmodule //结束模块

------------------------------machine.v------------------------

`timescale 1ns/1ns

module machine(inc_pc,load_acc,load_pc,rd,wr,load_ir,datactl_ena,halt,clk,zero,ena,opcode); //模块名machine,参数列表

output inc_pc,load_acc,load_pc,rd,wr,load_ir; //输出为inc_pc,load_acc,load_pc,rd,wr,load_ir output datactl_ena,halt; //输出为datactl_ena,halt

input clk,zero,ena; //输入为clk,zero,ena

input[2:0]opcode; //输入为3位的opcode

reg inc_pc,load_acc,load_pc,rd,wr,load_ir //定义寄存器型变量

reg datactl_ena,halt; //定义寄存器型变量datactl_ena,halt

reg[2:0]state; //定义3位的寄存器型变量state

parameter

HLT=3'b000,SKZ=3'B001,ADD=3'b010,ANDD=3'b011,XORR=3'b100,LDA=3'b101,STO=3'b110,JMP= 3'b111; //参数定义常量

always@(negedge clk) //时钟触发

begin

if(!ena) //接收复位信号RST,进行复位操作

begin

state<=3'b000; //state非阻塞赋值为3位的二进制数

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值4位的0

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值4位的0

end

else

ctl_cycle; //否则进入ctl_cycle任务

end

task ctl_cycle; //ctl_cycle任务

begin

casex(state)

3'b000: //载入高8位到struction

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0001; //非阻塞赋值4位的0

{wr,load_ir,datactl_ena,halt}<=4'b0100; //非阻塞赋值4位的0

state<=3'b001; //state非阻塞赋值赋为3位的1

end

3'b001: //pc增加来自低8位instruction

begin/

{inc_pc,load_acc,load_pc,rd}<=4'b1001; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0100; //非阻塞赋值

state<=3'b010; //非阻塞赋值

end

3'b010: //idle

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

state<=3'b011; //非阻塞赋值

end

3'b011: //分析指令从这里开始

begin

if(opcode==HLT) //指令为暂停HLT

begin

{inc_pc,load_acc,load_pc,rd}<=4'b1000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0001; //非阻塞赋值

end

else

begin

{inc_pc,load_acc,load_pc,rd}<=4'b1000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

state<=3'b100; //非阻塞赋值

end

3'b100: //fetch oprand

begin

if(opcode==JMP) //指令为暂停JMP

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0010; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA) //如果指令为暂停ADD,或者指令为暂停ANDD,或者指令为暂停XORR,或者指令为暂停LDA

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0001; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

if(opcode==STO) //如果指令为暂停STO

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0001; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

state<=3'b101; //非阻塞赋值

end

3'b101:

begin

if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA) //如果指令为暂停ADD,或者指令为暂停ANDD,或者指令为暂停XORR,或者指令为暂停

LDA

begin //过一个时钟后与累加内容进行运算

{inc_pc,load_acc,load_pc,rd}<=4'b0101; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

if(opcode==SKZ&&zero==1) //如果指令为暂停SKZ并且zero为1

begin

{inc_pc,load_acc,load_pc,rd}<=4'b1000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

if(opcode==JMP) //如果指令为暂停JMP

begin

{inc_pc,load_acc,load_pc,rd}<=4'b1001; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

if(opcode==STO) //如果指令为暂停STO

begin //过一个时钟后把wr变1就可以写到RAM中

{inc_pc,load_acc,load_pc,rd}<=4'b0000;//非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b1010; //非阻塞赋值

end

else

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000;//非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000;//非阻塞赋值

end

state<=3'b110; //非阻塞赋值

end

3'b110:

begin

if(opcode==STO) //指令为暂停STO

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0010; //非阻塞赋值

end

else

if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode||LDA) //如果指令为暂停ADD,或者指令为暂停ANDD,或者指令为暂停XORR,或者指令为暂停LDA

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0001; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

state<=3'b111; //非阻塞赋值

end

3'b111:

begin

if(opcode==SKZ&&zero==1) //如果指令为暂停SKZ并且zero为1

begin

{inc_pc,load_acc,load_pc,rd}<=4'b1000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

else

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

end

state<=3'b000; //非阻塞赋值

end

default:

begin

{inc_pc,load_acc,load_pc,rd}<=4'b0000; //非阻塞赋值

{wr,load_ir,datactl_ena,halt}<=4'b0000; //非阻塞赋值

state<=3'b000; //非阻塞赋值

end

endcase

end

endtask

endmodule

----------------------------addr_decode.v---------------------------

module addr_decode( addr ,rom_sel,ram_sel); //模块名addr_decode参数列表()output rom_sel,ram_sel; //输出rom-sel,ram_sel

input[12:0] addr; //输入13位的addr

reg rom_sel,ram_sel; //定义2个寄存器型变量rom_sel,ram_sel

always @(addr) //always模块addr触发

begin

casex(addr) //casex(变量名)

13'b1_1xxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b01;

13'b0_xxxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b10;

13'b1_0xxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b10;

default:{rom_sel,ram_sel}<=2'b00; //以上都不是则将0非阻塞赋值给(rom_sel,ram_sel)

endcase

end

Endmodule

-------------------------ram.v--------------------------

module ram(data,addr,ena,read,write); //模块名ram参数列表()

inout[7:0]data; //输入8位的data

input[9:0]addr; //输入10位的addr

input ena; //输入ena

input read,write; //输入read,write

reg[7:0]ram[10'h3ff:0]; //定义一个8位的寄存器型变量ram

assign data=(read&&ena)?ram[addr]:8'hzz; //若read&&ena为1,就把ram[addr]赋给data,否则就把高阻态赋给data

always@(posedge write) //always写触发模块

begin

ram[addr]<=data; //data非阻塞赋值赋给ram[addr]

end

Endmodule

--------------------------------rom.v-----------------------

module rom(data,addr,read,ena); //模块名rom参数列表()

output[7:0]data; //输出8位的data

input[12:0]addr; //输入13位的addr

input read,ena; //输入read,ena

reg[7:0]memory[12'h1fff:0]; //定义一个8位的寄存器型变量memory

wire[7:0]data; //定义一个8位的wire型变量data

assign data=(read&&ena)?memory[addr]:8'bzzzzzzzz; //若read&&ena为1,就把memory[addr]赋给data,否则就把高阻态赋给data

Endmodule

2.测试代码

-------------------------cputop.v---------------------

`include"addr_decode.v"

`include"accum.v"

`include"machinect1.v"

`timescale 1ns/1ns

`define PERIOD 100 // matches clk_gen.v

module cputop; //cputop模块

reg reset_req,clock; //定义寄存器型变量

integer test; //变量为有符号数

reg [(3*8):0]mnemonic; //array that holds 3 8 bit ASCII characters

reg[12:0]PC_addr,IR_addr; //寄存器型变量

wire[7:0]data; //定义wire型变量

wire[12:0]addr;//定义wire型变量

wire rd,wr,halt,ram_sel,rom_sel; //定义wire型变量

wire[2:0]opcode; //为布线后仿真做的专门添加的CPU内部信号线

wire[12:0]ir_addr,pc_addr; //为布线后仿真做的专门添加的CPU内部信号线

cpu

t_cpu(.clk(clock),.reset(reset_req),.halt(halt),.rd(rd),.wr(wr),.addr(addr),.data(alu_out),.opcode(o pcode),.fetch(fetch),.ir_addr(ir_addr),.pc_addr(pc_addr));

ram t_ram(.addr(addr[9:0]),.read(rd),.write(wr),.ena(ram_sel),.data(data));

rom t_rom(.addr(addr),.read(rd),.ena(rom_sel),.data(data));

addr_decode t_addr_decode(.addr(addr),.ram_sel(ram_sel),.rom_sel(rom_sel));

initial

begin

clock=1;

$timeformat(-9,1,"ns",12);//设定当前的时间格式

display_debug_message; //展示调试信息

sys_reset;

test1;

$stop;

test2;

$stop;

test3;

$finish;

end

task display_debug_message; //展示调试信息

begin

$display("\n********************"); //输出引用的附加的说明文字

$display("* THE FOLLOWING DEBUG TASK ARE AVAILABLE:*"); //输出引用的附加的说明文字$display("*\”test1;\“to load the 1st diagnostic program.*"); //输出引用的附加的说明文字$display("*\”test2;\“to load the 2nd diagnostic program.*"); //输出引用的附加的说明文字$display("*\”test3;\“to load the Fibonacci program.*"); //输出引用的附加的说明文字

end

endtask

task test1;

begin

test=0;

disable MONITOR;

$readmemb("test1.pro",t_rom.memory);//从文件中读取数据到存储器中

$display("rom loaded successfully!"); //输出引用的附加的说明文字

$readmemb("test1.dat",t_ram.ram);//从文件中读取数据到存储器中

$display("ram loaded successfully!"); //输出引用的附加的说明文字

#1 test=1;

#14800;

sys_reset;

end

endtask

task test2;

begin

test=0;

disable MONITOR;

$readmemb("test2.pro",t_rom.memory);//从文件中读取数据到存储器中

$display("rom loaded successfully!"); //输出引用的附加的说明文字

$readmemb("test2.dat",t_ram.ram);//从文件中读取数据到存储器中

$display("ram loaded successfully!"); //输出引用的附加的说明文字

#1 test=2;

#11600;

sys_reset;

end

endtask

task test3;

begin

test=0;

disable MONITOR;

$readmemb("test3.pro",t_rom.memory);//从文件中读取数据到存储器中

$display("rom loaded successfully!"); //输出引用的附加的说明文字

$readmemb("test3.dat",t_ram.ram);//从文件中读取数据到存储器中

$display("ram loaded successfully!"); //输出引用的附加的说明文字

#1 test=3;

#94000;

sys_reset;

end

endtask

task sys_reset;

begin

reset_req=0;

#(`PERIOD*0.7)reset_req=1;

#(1.5*`PERIOD)reset_req=0;

end

endtask

always @(test)//test触发

begin:MONITOR

case(test)

1:begin

$display("\n***RUNNING CUPtest1 - The Basic CPU Diagnostic Program ***"); //输出引用的附加的说明文字

$display("\n TIME PC INSTR ADDR DATA"); //输出引用的附加的说明文字

$display("----- --- ---- --- -----"); //输出引用的附加的说明文字

while(test==1) //当test为1时

@(t_cpu.pc_addr)

if((t_cpu.pc_addr%2==1)&&(t_cpu.fetch==1)) //如果t_cpu.pc_addr%2为1并且t_cpu.fetch==为1

begin

#60 PC_addr<=t_cpu.pc_addr-1; //非阻塞赋值

IR_addr<=t_cpu.ir_addr; //非阻塞赋值

#340 $strobe("%t %h %s %h %h",$time,PC_addr,mnemonic,IR_addr,data);//选通任务($strobe)要推迟到当前时阶结束时进行

end

end

2:begin

$display("\n***RUNNING CUPtest2 - The Basic CPU Diagnostic Program ***"); //输出引用的附加的说明文字

$display("\n TIME PC INSTR ADDR DATA"); //输出引用的附加的说明文字

$display("----- --- ---- --- -----"); //输出引用的附加的说明文字

while(test==2) //当test为2时

@(t_cpu.pc_addr)

if((t_cpu.pc_addr%2==1)&&(t_cpu.fetch==1)) //如果t_cpu.pc_addr%2为1并且t_cpu.fetch==为

begin

#60 PC_addr<=t_cpu.pc_addr-1; //非阻塞赋值

IR_addr<=t_cpu.ir_addr; //非阻塞赋值

#340 $strobe("%t %h %s %h %h",$time,PC_addr,mnemonic,IR_addr,data);//选通任务($strobe)要推迟到当前时阶结束时进行

end

end

3:begin

$display("\n***RUNNING CUPtest3 - The Basic CPU Diagnostic Program ***"); //输出引用的附加的说明文字

$display("\n TIME PC INSTR ADDR DATA"); //输出引用的附加的说明文字

$display("----- --- ---- --- -----"); //输出引用的附加的说明文字

while(test==3) //当test为3时

begin

wait(t_cpu.opcode!==3'h1)

$strobe("%t %d",$time,t_ram.ram[10'h2]);//选通任务($strobe)要推迟到当前时阶结束时进行wait(t_cpu.opcode!=3'h1);

end

end

endcase

end

always @(posedge halt) //当halt改变时触发模块

begin

#500

$display("\n********************"); //输出引用的附加的说明文字

$display("** A HALT INSTRUCTION WAS PROCESSED !!! **"); //输出引用的附加的说明文字$display("********************\n"); //输出引用的附加的说明文字

end

always#(`PERIOD/2)clock=~clock;

always@(t_cpu.opcode) //当t_cpu.opcode改变时触发模块

case(t_cpu.opcode)

3'b000:mnemonic="HALT";

3'h1:mnemonic="SKZ";

3'h2:mnemonic="ADD";

3'h3:mnemonic="AND";

3'h4:mnemonic="XOR";

3'h5:mnemonic="LDA";

3'h6:mnemonic="STO";

3'h7:mnemonic="JMP";

default:mnemonic="???";

endcase

Endmodule

-------------------------cpu.v-------------------------

`timescale 1ns/1ns

module cpu(clk,reset,halt,rd,wr,addr,data,opcode,fetch,ir_addr,pc_addr); //定义CPU模块input clk,reset; //输入变量为clk,reset

output rd,wr,halt; //输出变量为rd,wr,halt

output[12:0]addr; //13位输出变量addr

output[2:0]opcode; //3位输出变量opcode

output fetch; //输出变量fetch

output [12:0]ir_addr,pc_addr; //定义13位输出变量

inout[7:0]data; //8位输入变量data

wire clk,reset,halt; //定义wire型变量

wire[7:0] data; //定义wire型变量

wire[12:0] addr; //定义wire型变量

wire rd,wr; //定义wire型变量

wire fetch,alu_ena; //定义wire型变量

wire[2:0]opcode; //定义wire型变量

wire[12:0]ir_addr,pc_addr; //定义wire型变量

wire[7:0]alu_out,accum; //定义wire型变量

wire zero,inc_pc,load_acc,load_pc,load_ir,data_ena,contr_ena; //定义wire型变量

clk_gen m_clk_gen(.clk(clk),.reset(rest),.fetch(fetch),.alu_ena(alu_ena));

register m_reister(.data(data),.ena(load_ir),.rst(reset), .clk(clk),.opc_iraddr({opcode,ir_addr})); accum m_accum(.data(alu_out),.ena(load_acc),.clk(clk),.rst(reset),.accum(accum));

alum_alu(.data(data),.accum(accum),.clk(clk),.alu_ena(aln_ena),.opcode(opcode),.alu_out(alu_o ut),.zero(zero));

machinectl m_machinectl(.clk(clk),.rst(reset),.fetch(fetch),.ena(control_ena));

machinem_machine(.inc_pc(inc_pc),.load_acc(load_acc),.load_pc(load_pc),.rd(rd),.wr(wr),.load_i r(load_ir),.clk(clk),.datactl_ena(data_ena),.halt(halt),.zero(zero),.ena(contr_ena),.opcode(opcode) );

datactl m_datactl (.in(alu_out),.data_ena(data_ena),.data(data));

adr m_adr(.fetch(fetch),.ir_addr(ir_addr),.pc_addr(pc_addr),.addr(addr));

counterm_counter (.clock(inc_pc),.rst(reset),.ir_addr(ir_addr),.load(load_pc),.pc_addr(pc_addr)); endmodule

五.实验结果

如图所示

状态图:

六.实验结论

以上的报告文件中,揭示了综合器对综合过程和结果的分析,有及其重要意义。它能帮助我们了解系统运行的最高时钟,关键路径的最大延迟,使用的逻辑部件种类和数目。

经过以上实验可以看到,复杂的RISC_CPU设计其实是一个从抽象到具体的逐步接近的分析和实现过程。一个大型的CPU设计先从概念出发,用Verilog写出抽象的功能块描述,把许多跟复杂的的细节掩盖起来。然后,从行为级分析功能块之间的关系,通过仿真逐步验

证,发现问题,改动模块代码使其逐步趋向合理,并最后可以用RTL级Verilog源代码模块来表示。

数字系统设计与verilog HDL课程设计

数字系统设计与verilog HDL课程设计 设计题目:实用多功能数字钟 专业:电子信息科学与技术 班级:0313410 学号:031341025 姓名:杨存智 指导老师:黄双林

摘要 本课程设计利用QuartusII软件Verilog VHDL语言的基本运用设计一个多功能数字钟,经分析采用模块化设计方法,分别是顶层模块、alarm、alarm_time、counter_time、clk50mto1、led、switch、bitel、adder、sound_ddd、sound_ddd_du模块,再进行试验设计和软件仿真调试,分别实现时分秒计时、闹钟闹铃、时分秒手动校时、时分秒清零,时间保持和整点报时等多种基本功能。 单个模块调试达到预期目标,再将整体模块进行试验设计和软件仿真调试,已完全达到分块模式设计功能,并达到设计目标要求。 关键字:多功能数字钟、Verilog、模块、调试、仿真、功能

目录 1.课程设计的目的及任务............................................................. 错误!未定义书签。 1.1 课程设计的目的 (3) 1.2 课程设计的任务与要求 (4) 2.课程设计思路及其原理 (4) 3.QuartusII软件的应用 (5) 3.1工程建立及存盘 (5) 3.2工程项目的编译 (5) 3.3时序仿真 (6) 4.分模块设计、调试、仿真与结果分析 (7) 4.1 clk50mto1时钟分频模块 (7) 4.2 adder加法器模块 (7) 4.3 hexcounter16 进制计数器模块 (7) 4.4 counter_time 计时模块 (8) 4.5 alarm闹铃模块 (8) 4.6 sound_ddd嘀嘀嘀闹铃声模块 (9) 4.7 sound_ddd_du嘀嘀嘀—嘟声音模块 (9) 4.8 alarm_time闹钟时间设定模块 (10) 4.9 bitsel将输出解码成时分秒选择模块 (10) 4.10 switch去抖模块 (11) 4.11 led译码显示模块 (11) 4.12 clock顶层模块 (12) 5.实验总结 (13) 5.1调试中遇到的问题及解决的方法 (13) 5.2实验中积累的经验 (14) 5.3心得体会 (14) 6.参考文献 (14) 1.1 课程设计的目的 通过课程设计的锻炼,要求学生掌握V erilog HDL语言的一般设计方法,掌握VerilogHDL语言的基本运用,具备初步的独立设计能力,提高综合运用所学的理论知识独立分析和解决问题的能力,基于实践、源于实践,实践出真知,实践检验真理,培养学生的

verilog课程设计—交通灯

课程论文 论文题目基于DE2的交通灯设计完成时间 课程名称Verilog语言设计 任课老师 专业 年级

1.交通信号控制器设计要求与思路 1.1设计背景 FPGA是一种用户根据各自需要而自行构造逻辑功能的数字集成电路,其种类很多,内部结构也不同,但共同的特点是体积小、使用方便。本文介绍了用VerilogHDL语言设计交通灯控制器的方法,并在QuartusII系统对FPGA芯片进行编译下载,由于生成的是集成化的数字电路,没有传统设计中的接线问题,所以故障率低、可靠性高,而且体积非常小。本文通过EDA设计,利用VerilogHDL语言模拟仿真交通灯控制电路。 1.2设计要求 根据交通灯控制器要实现的功能,考虑用两个并行执行的always语句来分别控制A方向和B方向的3盏灯。这两个always语句使用同一个时钟信号,以进行同步,也就是说,两个进程的敏感信号是同一个。每个always语句控制一个方向的3种灯按如下顺序点亮,并往复循环:绿灯----黄灯----红灯,每种灯亮的时间采用一个减法计数器进行计数,计数器用同步预置数法设计,这样只需改变预置数据,就能改变计数器的模,因此每个方向只要一个计数器进行预置数就可以。为便于显示灯亮的时间,计数器的输出均采用BCD码,显示由4个数码管来完成,A方向和B方向各用两个数码管。设定A方向红灯、黄灯、绿灯亮的时间分别为:35s、5s、35s,B方向的红灯、黄灯、绿灯亮的时间分别为:35s、5s、35s。假如要改变这些时间,只需要改变计数器的预置数即可。 1.3设计思路 两个方向各种灯亮的时间能够进行设置和修改,此外,假设B方向是主干道,车流量大,因此B方向通行的时间应该比A方向长。交通灯控制器的状态转换表见下表。表中,1表示灯亮,0表示灯不亮。A方向和B方向的红黄绿分别用R1、Y1、G1、R2、Y2、G2来表示。

Verilog HDL数字时钟课程设计

课程设计报告 课程设计名称:EDA课程设计课程名称:数字时钟 二级学院:信息工程学院 专业:通信工程 班级:12通信1班 学号:1200304126 姓名:@#$% 成绩: 指导老师:方振汉 年月日

目录 第一部分 EDA技术的仿真 (3) 1奇偶校验器 (3) 1.1奇偶校验器的基本要求 (3) 1.2奇偶校验器的原理 (3) 1.3奇偶校验器的源代码及其仿真波形 (3) 28选1数据选择器 (4) 2.18选1数据选择器的基本要求 (4) 2.28选1数据选择器的原理 (4) 2.38选1数据选择器的源代码及其仿真波形 (5) 34位数值比较器 (6) 3.14位数值比较器的基本要求 (6) 3.24位数值比较器的原理 (6) 3.34位数值比较器的源代码及其仿真波形 (7) 第二部分 EDA技术的综合设计与仿真(数字时钟) (8) 1概述 (8) 2数字时钟的基本要求 (9) 3数字时钟的设计思路 (9) 3.1数字时钟的理论原理 (9) 3.2数字时钟的原理框图 (10) 4模块各功能的设计 (10) 4.1分频模块 (10) 4.2计数模块(分秒/小时) (11) 4.3数码管及显示模块 (13) 5系统仿真设计及波形图........................... 错误!未定义书签。5 5.1芯片引脚图.................................... 错误!未定义书签。5 5.2数字时钟仿真及验证结果 (16) 5.3数字时钟完整主程序 (17) 6课程设计小结 (23) 7心得与体会 (23) 参考文献 (24)

Verilog课程设计

一.实验目的 (1)学习RISC_CPU的基本结构和原理; (2)了解Verilog HDL仿真和综合工具的潜力; (3)展示Verilog设计方法对软/硬件联合设计和验证的意义; (4)学习并掌握一些常用的Verilog语法和验证方法。 二.实验原理 CPU即中央处理单元的英文缩写,它是计算机的核心部件。计算机进行信息处理可分为两个步骤: (1)将数据和程序(即指令序列)输入计算机的存储器中。 (2)从第一条指令的地址起开始执行该程序,得到所需结果,结束运行。CPU的作用是协调并控制计算机的各个部件并执行程序的指令序列,使其有条不紊地进行。因此它必须具有以下基本功能。 ①取指令——当程序忆在存储器中时,首先根据程序入口地址取出一条程序,为此要发出指令地址及控制信号。 ②分析指令——即指令译码,这是对当前取得的指令进行分析,指出它要求什么操作,并产生相应的操作控制命令。 ③执行指令——根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器、存储器及输入/输出设备的执行,实现每条指令的功能,其中包括对运算结果的处理以及下条指令地址的形成。 将CPU的功能进一步细化,可概括如下: (1)能对指令进行译码并执行规定的动作; (2)可以进行算术和逻辑运算; (3)能与存储器和外设交换数据; (4)提供整个系统所需要的控制。 尽管各种CPU的性能指标和结构细节各不相同,但它们所能完成的基本功能相同。由功能分析,可知任何一种CPU内部结构至少应包含下面这些部件:(1)算术逻辑运算部件(ALU); (2)累加器; (3)程序计数器;

(4)指令寄存器和译码器; (5)时序和控制部件。 三.实验内容 通过我们自己动手,设计出一个CPU的软核和固核。这个CPU是一个简化的专门为教学目的而设计的RISC_CPU。在设计中我们不但关心CPU总体设计的合理性,而且还使得构成这个RISC_CPU的每一个模块不仅是可仿真的也都可以综合成门级网表。因而从物理意义上说,这也是一个能真正通过具体电路结构而实现的CPU。为了能在这个虚拟的CPU上运行较为复杂的程序并进行仿真,把寻址空间规定为8K(即13们地址线)字节。 四.实验代码 1.源代码 //----------------------------------clk_gen.v------------------------------ `timescale 1ns/1ns //时间单位1ns,时间单位1ns module clk_gen(clk,reset,fetch,alu_ena); //模块名clk_gen,参数列表(clk,reset,fetch,alu_ena)input clk,reset; //输入clk,reset output fetch,alu_ena; //输出fetch,alu_ena wire clk,reset; //wire型变量clk,reset reg fetch,alu_ena; //reg寄存器型变量fetch,alu_ena reg[7:0]state; //reg寄存器型变量8位的state parameter S1=8'b00000001,S2=8'b00000010,S3=8'b00000100,S4=8'b00001000,S5=8'b00010000,S6=8'b001 00000,S7=8'b01000000,S8=8'b10000000,idle=8'b00000000; //参数型定义8位二进制常量s1,s2,s3,s4,s5,s6,s7,s8,idle always@(posedge clk) //always块时钟触发 if(reset) //如果reset为真 begin //执行begin,and顺序块 fetch<=0; //fetch非阻塞赋值赋为0 alu_ena<=0; //alu_ena非阻塞赋值赋为0 state<=idle; //idle非阻塞赋值给state end else //reset为假执行下面begin语句 begin case(state) //case表达式(state) S1:begin alu_ena<=1; //alu_ena非阻塞赋值赋为1 state<=S2; //state非阻塞赋值赋为S2 end S2:begin alu_ena<=0; //alu_ena非阻塞赋值赋为0 state<=S3; //state非阻塞赋值赋为S3 end

基于Verilog的课程设计

基于Verilog的课程设计 直流电机的PWM控制 指导老师:翁嘉民 班级:1031电气自动化技术成员:李高峰9112 王俊才9186 孟令朋9143

目录 1.绪论 (3) 直流电机介绍 (3) 1.1.1直流电机的特点 (3) 1.1.2直流电机的应用 (3) 介绍 (4) 介绍 (4) V ERILOG HDL硬件描述语言 (5) 1.4.1V ERILOG HDL硬件描述语言介绍 (5) 1.4.2V ERILOG HDL功能 (5) PWM脉冲宽度调制介绍 (6) 直流电机的PWM控制 (7) 2.设计原理 (8) 设计原理框图 (8) 原理图 (9) 模块设计 (9) 2.3.1 MOTO_TEST模块 (9) 2.3.4计数器模块 (12) 7实训心得 (13) 参考文献 (13)

直流电机的PWM控制器的设计 1.绪论 直流电机介绍 直流电机是实现直流电能与机械能之间相互转换的一种电力机械,按照直流电机的用途分为直流电动机和直流发电机两类。能够将机械能转换成直流电能的电机称为直流发电机;能够将直流电能转换成机械能的电机称为直流电动机。 1.1.1直流电机的特点 从直流电机与交流电机相比中可以看出,直流电机具有优良的调速性能和启动性能。直流电机具有宽广的调速范围,平滑的无级调速特性,可实现频繁的无级快速启动、制动和反转;过载能力大,能承受频繁的冲击负载;能满足自动化生产系统中各种特殊运行的要求。而直流发电机则能提供无脉动的大功率直流电源,且输出电压可以精确地调节和控制。 1.1.2直流电机的应用 直流电机是交通、工矿、建筑等行业中的常见动力机械,是机电行业人员的重要工作对象和工具。在某些要求调速范围广、速度快、精密度高、控制性能优异的场合,直流电机的应用目前仍占有较大的比重,如大型可逆式轧钢机、内燃机车、矿井卷扬机、造纸和印刷机械、宾馆高速电梯、城市电车、电动自行车、龙门刨床、电力机车、地铁列车、船舶机械、大型精密机床和大型起重机等生产机械中。

Verilog HDL课程设计

人民武装学院Verilog HDL课程设计洗衣机控制器的设计 学生姓名: 周云 学号: PB102027115 专业: 电子信息科学与技术 年级: 2010 级 指导老师: 周骅老师 时间: 2011年12月22日

目录 引言...................................................................................................................... - 3 - 一、设计内容...................................................................................................... - 4 - 1.设计内容.................................................................................................... - 4 - 2.功能............................................................................................................ - 4 - 二、洗衣机控制器的工作原理.......................................................................... - 6 - 1. 洗衣机的工作状态.................................................................................. - 6 - 2. 全自动洗衣过程...................................................................................... - 7 - 3.单独执行某个洗衣程序............................................................................ - 8 - 三、洗衣机的状态转换图.................................................................................. - 9 - 1.洗衣机的状态转换图................................................................................ - 9 - 2. 设计思路.................................................................................................. - 9 - 四、设计程序.................................................................................................... - 11 - 1.全自动洗衣机主程序.............................................................................. - 11 - 2.全自动洗衣机测试程序.......................................................................... - 15 - 五、步骤及仿真图............................................................................................ - 17 - 1.在代码提示框架中完成核心子模块wash_ctrl.v的设计 ................... - 17 - 2.对核心子模块wash_ctrl.v 进行时序仿真 ........................................... - 17 - 六、功能图........................................................................................................ - 20 - 1.设计顶层图形文件,编译.................................................................... - 20 - 2.功能引脚锁定.......................................................................................... - 20 - 心得体会............................................................................................................ - 22 -

《EDA技术与Verilog_HDL》清华第2版习题1

第章EDA技术概述

1-1 EDA技术与ASIC设计和FPGA开发有什么关系?FPGA在ASIC设计中有什么用途? 答:EDA技术进行电子系统设计的最后目标,是完成专用集成电路(ASIC)的设计和实现,FPGA是实现这一途径的主流器件,它们的特点是直接面向用户、具有极大的灵活性和通用性、使用方便、硬件测试和实现快捷、开发效率高、成本低、上市时间短、技术维护简单、工作可靠性好等。FPGA的应用是EDA技术有机融合软硬件电子设计技术、ASIC设计,以及对自动设计与自动实现最典型的诠释。 1-2 与软件描述语言相比,Verilog有什么特点? 答:Verilog语言的特点: (1)按照设计目的,Verilog程序可以划分为面向仿真和面向综合两类,而可综合的Verilog程序能分别面向FPGA和ASIC开发两个领域。 (2)能在多个层次上对所设计的系统加以描述,从开关级、门级、寄存器传输级(RTL)至行为级都可以加以描述。 (3)灵活多样的电路描述风格。

1-3 什么是综合?有哪些类型?综合在电子设计自动化中的地位是什么?答:综合(Synthesis),就其字面含义应该是:把抽象的实体结合成单个或统一的实体。 在电子设计领域,综合的概念可以表述为:将用行为和功能层次表达的电子系统转换为低层次的、便于具体实现的模块组合装配的过程。 (1)从自然语言转换到Verilog语言算法表述,即自然语言综合。 (2)从算法表述转换到寄存器传输级(Register Transport Level,RTL)表述,即从行为域到结构域的综合,也称行为综合。 (3)从RTL级表述转换到逻辑门(包括触发器)的表述,即逻辑综合。(4)从逻辑门表述转换到版图级表述(如ASIC设计),或转换到FPGA的配置网表文件,可称为版图综合或结构综合。 综合器就是能够将一种设计表述形式自动向另一种设计表述形式转换的计算机程序,或协助进行手工转换的程序。它可以将高层次的表述转化为低层次的表述,可以将行为域转化为结构域,可以将高一级抽象的电路描述(如算法级)转化为低一级的电路描述(如门级),并可以用某种特定的“技术”(如CMOS)实现。

verilog课程设计—交通灯1

课程设计 课程名称__EDA技术综合设计与实践__ 题目名称交通灯控制系统 学生学院信息工程学院 专业班级通信工程08(4) 学号 3108002925 学生姓名高高 指导教师李学易 2011 年12 月26 日

基于FPGA 的交通灯控制器的设计 摘要:Verilog 是广泛应用的硬件描述语言,可以用在硬件设计流程的建模、综合和模拟等多个阶段。随着硬件设计规模的不断扩大,应用硬件描述语言进行描述的CPLD 结构,成为设计专用集成电路和其他集成电路的主流。现代城市在日常运行控制中,越来越多的使用红绿灯对交通进行指挥和管理。而一套完整的交通灯控制系统通常要实现自动控制和手动控制去实现其红绿灯的转换。 基于FPGA 设计的交通灯控制系统电路简单、可靠性好。本设计利用Verilog HDL 语言、采用层次化混合输入方式,可控制4个路口的红、黄、绿、左转四盏信号灯,让其按特定的规律进行变化。在QUARTUSⅡ下对系统进行了综合与仿真。仿真结果表明系统可实现十字路口红绿灯及左转弯控制和倒计时显示,并能够自动控制交通灯转变。通过应用Verilog HDL 对交通灯控制器的设计,达到对Verilog HDL 的理解 关键词:FPGA;交通灯自动控制;V erilog HDL;Quartus Ⅱ 1.交通信号控制器设计要求与思路 1.1设计要求 在交通灯系统中(图1),路口1、2、3、4均需要红、黄、绿、左转四盏灯(用RYGL分别表示) ,并且每个路口都需要一个倒数的计时器,假设绿灯每次维持的时间是40 s ,黄灯为5 s ,左转灯10s,红灯60s,黄灯亮时以一定的频率闪动。交通灯系统大多是自动控制来指挥交通的,但有时需要由交警手动控制红绿灯,所以要求设 计的该交通信号系统需要具有该功能。 实现设计目标如下: (1)设计一个十字路口的交通灯控制电路,每条路配有红、黄、绿交通信号灯,通过电路对十字路口的两组交通灯的状态实现自动循环控制; (2)实现东西车道和南北车道上的车辆交替运行,绿灯每次维持的时间是40 s ,黄灯为5 s ,左转灯10s,红灯60s; (3)要求黄灯亮5 秒后,红灯才能转为绿灯,黄灯亮时以一定的频率闪动; (4)东西车道和南北车道每次通行的时间不同且可调; 图1 交通灯系统示意图

EDA技术与Verilog HDL技术实验报告

EDA技术与Verilog HDL技术实验报告 班级:09电信实验班姓名:虞鸿鸣组别:Q09610137 实验:交通灯控制 一、实验目的: 1、运用Verilog HDL综合编辑软件实现相应功能; 2、进一步使用EDA技术解决实际问题; 3、进一步使用EDA工具箱,提高对硬件电路的认识。 二、实验仪器 PC计算机、EDA实验工具箱 三、简要原理 1. 能显示十字路口东西、南北两个方向的红、黄、绿的指示状态 用两组红、黄、绿三色灯作为两个方向的红、黄、绿灯。变化规律为:东西绿灯,南北红灯→东西黄灯,南北红灯→东西红灯,南北绿灯→东西红灯,南北黄灯→东西绿灯,南北红灯……依次循环。 2. 能实现正常的倒计时功能 用两组数码管作为东西和南北方向的允许或通行时间的倒计时显示,显示时间为红灯45秒、绿灯40秒、黄灯5秒。 3. 能实现紧急状态处理的功能 (1) 出现紧急状态(例如消防车,警车执行特殊任务时要优先通行)时,两路上所有车禁止通行,红灯全亮; (2) 显示到计时的两组数码管闪烁; (3) 计数器停止计数并保持在原来的状态; (4) 特殊状态解除后能返回原来状态继续运行。 4. 能实现系统复位功能 系统复位后,东西绿灯,南北红灯,东西计时器显示40秒,南北显示45秒。 5. 用VHDL语言设计符合上述功能要求的交通灯控制器,并用层次化设计方法设计该电路。 6. 控制器、置数器的功能用功能仿真的方法验证,可通过有关波形确认电

路设计是否正确。 7. 完成电路全部设计后,通过系统实验箱下载验证设计课题的正确性。 四、设计思路 EN、CLK、RST、URGEN分别为使能信号、时钟信号、复位信号和紧急情况信号; num1,num2分别为东西方向的倒计时和南北方向的倒计时,两个八位数码管,硬件接有译码芯片; light1,light2分别为东西方向的交通灯和南北方向的交通灯中红、黄、绿三色位置; tim1,tim2分别为东西和南北方向的交通的灯控制信号,高电平时有效; pb1,pb2分别为寄存紧急情况前交通灯状态变量的标志信号,高电平有效; state1,state2分别为东西、南北方向的交通灯状态信号,每个方向有三种状态,即00、01、11; 五、源代码及注析 module TRAFFIC_LI(EN,CLK,RST,URGEN,num1,num2,light1,light2); input EN,CLK,RST,URGEN;//EN、CLK、RST、URGEN分别为使能信号、时钟信号、复位信号和紧急情况信号 output[7:0] num1,num2;//num1,num2分别为东西方向的倒计时和南北方向的倒计时,两个八位数码管,硬件接有译码芯片 output[2:0] light1,light2;//light1,light2分别为东西方向的交通灯和南北方向的交通灯中红、黄、绿三色位置 reg tim1,tim2,pb1,pb2;//tim1,tim2分别为东西和南北方向的交通的灯控制信号,高电平时有效 //pb1,pb2分别为寄存紧急情况前交通灯状态变量的标志信号,高电平有效 reg[1:0]state1,state2;//state1,state2分别为东西、南北方向的交通灯状态信号,每个方向有三种状态,即00、01、11 reg[2:0]light1,light2,light3,light4;//light3,light4用以寄存紧急情况前交通灯

verilog课程设计

课程设计 设计题目:基于FPGA的乐曲演奏电路设计 ?指导教师:蒋俊华 ?学院:物理与电子学院 ?专业:电子信息科学与技术 ?姓名:郭志勇 ?学号:10230******* ?实验地点:特种功能实验室(实验室502)

摘要:本文根据层次化的设计思路并在EDA开发工具Quartus II 9.0 (32-Bit) 平台上,采用Verilog语言、原理图、定制LPM-ROM块以及实例化的设计方法,利用数控分频的原理实现了基于FPGA片上系统(本实验用的是康芯GW48系列EDA设备)乐曲演奏的设计。 关键词 FPGA,EDA,Verilog,数控分频器 一. 概述部分: (1)设计所要实现的功能 能够很好的演奏出“梁祝”的谱子,将音乐通过实验箱上的喇叭播放出;演奏发音相对应的简谱码输出显示由在数码管5显示;高八度音指示由发光管D5指示 (2)设计所采用的基本思想 根据层次化的设计思路,可把乐曲硬件演奏电路分为3个模块,音乐节拍发生模块,音符译码电路模块,数控分频模块。 音乐节拍发生模块的设计:将编辑好的音符填入MIF文件中再定制LPM-ROM块将音符数据加载入ROM再通过计数器逐步计数rom块的地址来提取音符;音符译码电路模块、数控分频模块的设计:都是由verilog代码实例化生成 通过输入原理图的方法将各个模块连接起来生成一个block块的.qpf文件作为最终的顶层文件。 二.系统设计部分 (1)整个设计的组织结构

(2)各个子单元的设计思路 音乐节拍发生模块的设计: LPM-ROM块该模块为音乐曲谱的存放块。其中设置了“梁祝”乐曲全部音符所对应的分频预置数。其利用LPM_ROM宏模块将共设定256个音符,每个音符宽度为4位。 Mif文件存放乐曲中的音符数据,它是利用LPM-ROM来实现的,将乐谱中相应的音符放在一个连续的地址上。它首先是编写音符数据文件,将乐谱中相应的音符存放在一个连续的地址上。因为1拍的时间定为1秒,提供的是4Hz的时钟频率(即1/4拍的整数倍),则需将这个音符存储在相应次数的连续几个地址上。.mif文件如下:

哈工大Verilog课程设计-状态机

可编程逻辑器件大作业(二) 2012年12月

一、题目 利用Verilog HDL设计一个电路,对输入的一串二进制数,用于检测序列中连续3个或者3个以上的1,状态转换图如图所示。要求: 1、编写源程序; 2、给出仿真电路图、状态转换图和仿真波形图 二、程序代码 module moore(clk,din,op,reset); input clk,din,reset; output op; reg[1:0] current_state,next_state; reg op; parameter S0=2'b00,S1=2'b01,S2=2'b10,S3=2'b11; always @ (posedge clk) begin if(!reset) current_state = S0; else current_state <= next_state; end always @ (din or current_state)

begin case( current_state ) S0: begin op = 0; if(din == 0) next_state = S0; else next_state = S1; end S1: begin op = 0; if(din == 0) next_state = S0; else next_state = S2; end S2: begin op = 0; if(din == 0) next_state = S0; else next_state = S3; end S3: begin op = 1; if(din == 0) next_state = S0;

数字竞赛抢答器课程设计Verilog语言实现

数字竞赛抢答器课程设计Verilog语言实现

可编程器件与应用课程设计报告 姓名:XXX 学号:XXXXXXXXXX 专业班级:信息XXX 题目:数字式竞赛抢答器 指导老师:

一、绪论 背景: 随着电子技术的发展,可编程逻辑器件(PLD)的出现,使得电子系统的设计者利用EDA(电子设计自动化)软件,就可以独立设计自己的专用集成电路(ASIC)器件。可编程逻辑器件是一种半导体集成器件的半成品。在可编程逻辑器件的芯片中按一定方式(阵列形式或单元阵列形式)制作了大量的门、触发器等基本逻辑器件,对这些基本器件适当地连接,就可以完成某个电路或系统的功能。 数字式竞赛抢答器控制系统是工厂、学校和电视台等单位举办各种智力竞赛等娱乐活动中经常使用的重要基础设备之一。目前设计抢答器的方法很多,例如用传统的PCB板设计、用PIC 设计或者用单片机设计。而用Verilog可以更加快速、灵活地设计出符合各种要求的抢答器,优于其他设计方法,使设计过程达到高度自动化。本文介绍的4路数字式竞赛抢答器基于Verilog 语言、以EDA技术作为开发手段、采用CPLD (复杂的可编程逻辑器件)作为控制核心设计而成。与传统设计相比较,不仅简化了接口和控制,

也提高了系统的整体性能和工作可靠性,具有电路简单、成本低廉、操作方便、灵敏可靠等优点。意义: 数字式竞赛抢答器作为一种电子产品,早已广泛应用于各种智力和知识竞赛场合,但目前所使用的抢答器存在分立元件使用较多,造成每路的成本偏高,而现代电子技术的发展要求电子电路朝数字化、集成化方向发展,因此设计出数字化全集成电路的多路抢答器是现代电子技术发展的要求。 二、实现方案 设计要求: 1、设计一个可容纳4组参赛的数字式抢答器,每组设一个按钮,供抢答使用。 2、抢答器具有第一信号鉴别和锁存功能,使除第一抢答者外的按钮不起作用。 3、设置一个主持人“复位”按钮。 4、主持人复位后,开始抢答,第一信号鉴别锁存电路得到信号后,有指示灯显示抢答组别,扬声器发出2~3秒的音响。 5、设置一个计分电路,每组开始预置5分,由主持人记分,答对一次加1分,答错一次减1分。

数字竞赛抢答器课程设计Verilog语言实现

可编程器件与应用课程设计报告 姓名: XXX 学号: XXXXXXXXXX 专业班级:信息XXX 题目数字式竞赛抢答器 指导老师:

、绪论 背景: 随着电子技术的发展,可编程逻辑器件(PLD )的出现,使得电子系统的设计者利用 EDA (电子设计自动化)软件,就可以独立设计自己的专用集成电路(ASIC )器件。可编 程逻辑器件是一种半导体集成器件的半成品。在可编程逻辑器件的芯片中按一定方式(阵列形式或单元阵列形式)制作了大量的门、触发器等基本逻辑器件,对这些基本器件适当地连接,就可以完成某个电路或系统的功能。 数字式竞赛抢答器控制系统是工厂、学校和电视台等单位举办各种智力竞赛等娱乐活动中经常使用的重要基础设备之一。目前设计抢答器的方法很多,例如用传统的PCB板设计、 用PIC设计或者用单片机设计。而用Verilog可以更加快速、灵活地设计出符合各种要求的 抢答器,优于其他设计方法,使设计过程达到高度自动化。本文介绍的4路数字式竞赛抢答 器基于Verilog语言、以EDA技术作为开发手段、采用CPLD (复杂的可编程逻辑器件)作为控制核心设计而成。与传统设计相比较,不仅简化了接口和控制,也提高了系统的整体性 能和工作可靠性,具有电路简单、成本低廉、操作方便、灵敏可靠等优点。意义:数字式竞赛抢答器作为一种电子产品,早已广泛应用于各种智力和知识竞赛场合,但目前所使用的抢答器存在分立元件使用较多,造成每路的成本偏高,而现代电子技术的发展要 求电子电路朝数字化、集成化方向发展,因此设计出数字化全集成电路的多路抢答器是现代 电子技术发展的要求。 实现方案 设计要求: 1设计一个可容纳4组参赛的数字式抢答器,每组设一个按钮,供抢答使用。 2、抢答器具有第一信号鉴别和锁存功能,使除第一抢答者外的按钮不起作用。 3、设置一个主持人“复位”按钮。 4、主持人复位后,开始抢答,第一信号鉴别锁存电路得到信号后,有指示灯显示抢答组别, 扬声器发出2~3秒的音响。 5、设置一个计分电路,每组开始预置5分,由主持人记分,答对一次加1分,答错一次减 1分。 6、设置犯规电路,对超时答题(例如1分钟)的组别鸣笛示警,并由组别显示电路显示出犯规组别,该轮该选手退出,由裁判员重新发令,其他人再抢答。 此设计问题可分为第一信号鉴别、锁存模块,答题计时电路模块,计分电路模块和扫描 显示模块四部分。 第一信号鉴别锁存模块的关键是准确判断出第一抢答者并将其锁存,在得到第一信号后,将输入端封锁,使其他组的抢答信号无效,可以用触发器或锁存器实现。设置抢答按钮 K1、K2、K3、K4,主持人复位信号judge,蜂鸣器驱动信号buzzout。judge=O时,第一信号鉴别、锁存电路、答题计时电路复位,在此状态下,若有抢答按钮按下,鸣笛示警并显示犯规组别;judge=1时,开始抢答,由第一信号鉴别锁存电路形成第一抢答信号,进行组别显示,控制蜂鸣器发出声响,并启动答题计时电路,若计时时间到,主持人复位信号还没有按下,则由蜂鸣器发出犯规示警声。 计分电路是一个相对独立的模块,采用十进制加/减计数器、数码管数码扫描显示,设 置复位信号Reset、加减分信号add_min,加减分状态键key_state, Reset=0时所有得分回到 起始分(5分),且加、减分信号无效;Reset=1时,由第一信号鉴别、锁存电路的输出信号 选择进行加减分的组别,当key_state=1时,按一次add_min,第一抢答组加1分;当key_state=O

eda技术与veriloghdl实验报告

EDA技术与Verilog HDL 实验报告 学生姓名:樊奇峰 学生学号: 所在班级:10级电科(2)班 实验老师:陈亮亮 实验地点地点:理工楼

实验一 EDA实验箱使用 一.实验目的 1.GW48教学实验系统原理与使用介绍 2.熟悉QuartusII两种输入方式下编译、仿真简单的组合电路。 二.实验内容 首先了解GW48系统使用注意事项以及GW48系统主板结构与使用方法,接着对各实验电路结构图特点与适用范围简述。最后在QuartusII界面下,用文本输入和图形输入分别验证七选一多路选择器的功能。 三.程序清单 文本输入如下所示: module mux71(a,b,c,d,e,f,g,s,y); input a,b,c,d,e,f,g; output y; input [2:0] s; reg y ; always @(a,b,c,d,e,f,g,s) case (s) 0: y<=a; 1: y<=b; 2: y<=c; 3: y<=d; 4: y<=e; 5: y<=f; 6: y<=g; default: y<=a; endcase

endmodule 图形输入如下所示: 四、实验步骤 1、新建一个名称为MUX71a的工程,并在该文件夹中新建一个的文件。 2、编译代码,编译成功后进行第三步,若不成功则查改代码中的错误。 3、在工程文件夹中新建一个的波形文件,导入工程端口,设置输入波形,仿真得出输出端口波形。 4、验证输出端口波形是否达到七选一多路选择器的功能。 五、实验数据 仿真波形如下图所示。 六、实验小结 通过对EDA实验箱使用,了解了GW48教学实验系统原理与使用介绍;

Verilog数字钟课程设计

课程设计报告课程设计题目:数字钟系统设计 学号:2 学生姓名:刘新强 专业:通信工程 班级:1421302 指导教师:钟凯 2016年1月4日

FPGA( Field Programmable Gate Array,现场可编程门阵列),一种可编程逻辑器件,是目前数字系统设计的主要硬件基础。可编程逻辑器件的设计过程是利用EDA 开发软件和编程和编程工具对器件进行开发的过程。 通过modelsim软件下采用verilog语言实现数字钟系统设计,实现了以下几个方面的功能: 1.数字钟基本计时功能 2.数字钟校时功能 3.数字钟系统报时功能 关键词:FPGA ;VHDL;数字钟

一、FPGA与VHDL简介 (1) 1、FPGA与简介 ........................................................................................... 2、VHDL简介 ............................................................................................... 二、课程设计的目的与要求 (2) 1、教学目的.................................................................................................................... 2、教学要求.................................................................................................................... 3、数字钟系统设计要求................................................................................................ 三、设计方案 (2) 1、系统框图.................................................................................................................... 2、模块说明.................................................................................................................... 四、仿真与实现 (3) 1、数字钟基本计时功能实现........................................................................................ 2、数字钟校时功能实现................................................................................................ 3、数字钟系统报时功能实现........................................................................................ 五、实验心得 (4) 六、参考文献 (4) 七、代码 (5)

verilog HDL课设(数字钟)

课程设计(报告)任务书 (理工科类) Ⅰ、课程设计(报告)题目: 实时时钟电路的设计 Ⅱ、课程设计(论文)工作内容 一、课程设计目标 《硬件描述语言》是一门技术性、应用性很强的学科,实验课教学是它的一个极为重要的环节。不论理论学习还是实际应用,都离不开实验课教学。如果不在切实认真地抓好学生的实践技能的锻炼上下功夫,单凭课堂理论课学习,势必出现理论与实践脱节、学习与应用脱节的局面。《HDL项目设计》的目的就是让同学们在理论学习的基础上,通过完成一个涉及时序逻辑、组合逻辑、声光输出的,具有实用性、趣味性的小系统设计,使学生不但能够将课堂上学到的理论知识与实际应用结合起来,而且能够对分析、解决实际的数字电路问题进一步加深认识,为今后能够独立进行某些数字应用系统的开发设计工作打下一定的基础。 二、课程设计任务与要求 (1)设计一个数码管实时显示时、分、秒的数字时钟(24小时显示模式); (2)为了演示方便,应具有分钟、小时快进功能; (3)时、分、秒设置功能(选作)。 三、课程设计考核 平时20%;验收40%;报告40%

摘要 数字钟是人们日常生活中经常使用的计时工具,本次的课程设计是基于Verilog HDL的多功能数字钟,完成时、分、秒的显示功能。设计利用Verilog HDL 语言自顶向下的设计理念,突出其作为硬件描述语言的良好的可读性、可移植性以及易于理解等优点。通过Quartus II 5.0和ModelSim SE 6.1f软件完成仿真、综合。程序下载到FPGA芯片后,可用于实际的数字钟显示中。 此次设计的逻辑结构主要由分频器、计数器和译码显示器三个模块构成。分频模块将50Mhz系统基准时钟分频产生两路时钟信号,一路是1HZ的数字钟计时工作频率,一路是数码管动态显示的扫描频率;计时模块对1HZ的时钟信号进行计时,分为时、分、秒三个部分;译码显示模块采用动态扫描的方式完成数码管的显示。最后通过主模块调用三个子模块函数完成整个设计。 【关键词】硬件描述语言FPGA 数字钟动态显示

相关文档
最新文档