verilog 实现的0-9 计数器数码管显示_Projects@更相减损术求最大公约数的Verilog实现...

该博客介绍了使用Verilog在数字电路实验中实现更相减损术求最大公约数的过程。内容包括问题背景、题目要求和问题分析。设计包括计算、储存和显示三个部分,采用Von Neumann结构,使用FSM控制单元和数据通路。最终完成了仿真和板级验证。
摘要由CSDN通过智能技术生成

(提醒:此作业仅供参考学习,有缺点或问题可提出。)

大二上学期数字电路实验:更相减损术求最大公约数的Verilog实现。

问题背景:

《九章算术》中记载求两正整数最大公约数的更相减损术:“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。”请设计一个Verilog程序实现更相减损术。

题目要求:

Finish the verilog code above using Digital Processor structure

Simulation with your own testbench

Synthesis

Diagram of structure and STD should be included

问题分析:

使用一个顶层模块和若干模块来实现计算、储存和显示等功能。

程序整体采用Von neumann structure,分为了计算部分(Datapath、Controlunit)、储存部分(RAM)、显示部分(Displayer)四个module。计算部分Controlunit采用Finiteness States Machine的运行方式,Datapath则用于实现更相减损术的具体操作。

计算部分总体概括图:

0fabac9d88009e912118a884ea48de87.png

Datapath部分:

e9b28377917eddc4ec96c43c29b4c81c.png

Controlunit部分:

60b69e6bd2d86968cc4047a5f1341671.png

储存部分使用IP自动生成一个8×2的RAM模块来实现。

显示部分采用7段数码管实现。

Module部分代码:

顶层模块:

`timescale 1ns / 1ps

module GCD_Top(
    input clk,
    input clr,
    input go,
    input xsig,
    input ysig,
    input wea,
    input addra,
    input [7:0] dina,
    output [7:0] douta,
    output [7:0] gcd,
    output [6:0] a_to_g,
    output [3:0] an);
    
    wire xmsel,ymsel,eqflg,ltflg,xld,yld,gld;
    reg [7:0] xin;
    reg [7:0] yin;
    
    always @ (posedge clk)
    begin
    if(xsig == 1)
        xin <= douta;
    else if(ysig == 1)
        yin <= douta;
    end
    
    GCD_Datatpath U1(
    .clk(clk),
    .clr(clr),
    .xmsel(xmsel),
    .ymsel(ymsel),
    .xin(xin),
    .yin(yin),
    .gcd(gcd),
    .eqflg(eqflg),
    .ltflg(ltflg),
    .xld(xld),
    .yld(yld),
    .gld(gld));
    
    GCD_Controlunit U2(
    .clk(clk),
    .clr(clr),
    .go(go),
    .eqflg(eqflg),
    .ltflg(ltflg),
    .xmsel(xmsel),
    .ymsel(ymsel),
    .xld(xld),
    .yld(yld),
    .gld(gld));
    
    GCD_RAM U3(
    .clka(clk),
    .wea(wea),
    .addra(addra),
    .dina(dina),
    .douta(douta));
    
    GCD_Displayer U4(
    .clk(clk),
    .clr(clr),
    .x(gcd),
    .a_to_g(a_to_g),
    .an(an));
    
endmodule

Datapath模块:

`timescale 1ns / 1ps

module GCD_Datatpath(
    input clk,
    input clr,
    input xmsel,
    input ymsel,
    input xld,
    input yld,
    input gld,
    input [7:0] xin,
    input [7:0] yin,
    output [7:0] gcd,
    output reg eqflg,
    output reg ltflg);
    
    wire [7:0] xmy, ymx;
    reg [7:0] x, y, xl, yl, gcd_out;
    
    assign xmy = x - y;
    assign ymx = y - x;
    
    always @(*) begin //eqf lag 
    if (x == y)
        eqflg <= 1'b1;
    else
        eqflg <= 1'b0;
    end
    
    always @(*) begin //ltflag 
    if (x < y)
        ltflg <= 1'b1;
    else if(x > y)
        ltflg <= 1'b0;
    end
    
    always @(*) begin //mux_x; 
    if (xmsel == 1)
        xl <= xin; 
    else if(ltflg == 0)
        xl <= xmy;
    end
    
    always @(*) begin //muxy;
    if (ymsel == 1)
       yl <= yin; 
    else if(ltflg == 1)
         yl <= ymx;
    end
    
    always@ (posedge clk) begin //reg_x 
    if (clr == 1)
        x <= 0;
    else if (xld == 1)
        x <= xl; 
    end
    
    always@ (posedge clk) begin //reg_y 
    if (clr == 1)
        y <= 0;
    else if (yld == 1)
        y <= yl; 
    end
    
    always@ (posedge clk) begin //reggcd
    if (clr == 1)
        gcd_out <= 0;
    else if (gld == 1)
        gcd_out <= x;
    end
    
    assign gcd = gcd_out;
    
    endmodule

Controlunit模块:

`timescale 1ns / 1ps

module GCD_Controlunit(
    input clk,
    input clr,
    input go,
    input eqflg,
    input ltflg,
    output reg xmsel,
    output reg ymsel,
    output reg xld,
    output reg yld,
    output reg gld);
    
    reg [2:0] current_state,next_state;
    
    parameter start = 3'b000;
    parameter input1 = 3'b001;
    parameter test1 = 3'b010;
    parameter test2 = 3'b011;
    parameter update1 = 3'b100;
    parameter update2 = 3'b110;
    parameter done = 3'b111;//state register

    always @(posedge clk) begin
    if (clr == 1)
        current_state <= start;
    else
        current_state <= next_state;
    end

//next sate logic
    always @(*) begin
    case(current_state)
    start:
    if(go == 1)
        next_state = input1;
    else
        next_state = start;
    input1:
        next_state = test1;
    test1:
    if(eqflg == 1)
        next_state = done;
    else
        next_state = test2;
    test2:
    if(ltflg == 1)
        next_state = update1;
    else
        next_state = update2;
    update1:
    next_state = test1;
    update2:
    next_state = test1;
    done:
    next_state = start;
    default:
    next_state = start;
    endcase
    end
    
//output logic
    always @(*)begin
    if (clr == 1)
        {xmsel,ymsel,xld,yld,gld} = 5'b00000;
    else
    case(current_state)
    start:
        {xmsel,ymsel,xld,yld,gld} = 5'b00000;
    input1:
            {xmsel,ymsel,xld,yld,gld} = 5'b11110;
    update1:
            {xmsel,ymsel,xld,yld,gld} = 5'b00010;
    update2:
            {xmsel,ymsel,xld,yld,gld} = 5'b00100;
    done:
            {xmsel,ymsel,xld,yld,gld} = 5'b00001;
    default:
            {xmsel,ymsel,xld,yld,gld} = 5'b00000;
    endcase
    end

endmodule

RAM模块:(偷懒用IP生成的,照搬代码运行会出错,具体操作自行查阅)

`timescale 1ns / 1ps

module GCD_RAM(
    input wire clka,
    input wire  wea,
    input wire  addra,
    input wire [7:0] dina,
    output wire [7:0] douta);
    
    blk_mem_gen_0 your_instance_name (
  .clka(clka),
  .wea(wea),
  .addra(addra),
  .dina(dina),
  .douta(douta)
);

endmodule

显示模块:

`timescale 1ns / 1ps

module GCD_Displayer(
    input clk,
	input clr,
	input [15: 0] x,
	output reg [6: 0] a_to_g,
	output reg [3: 0] an
	);

	wire [1: 0] s;
	reg [3: 0] digit;
	reg [19: 0] clkdiv;

	assign s = clkdiv[19:18];
 

	always @(posedge clk)
		case(s)
			0: digit = x[3: 0];
			1: digit = x[7: 4];
			2: digit = x[11: 8];
			3: digit = x[15: 12];
			default: digit = x[3: 0];
		endcase

	always @(posedge clk) begin
		case(digit)  
			0: a_to_g = 7'b1111_110;  // 1
			1: a_to_g = 7'b0110_000;  // 1
			2: a_to_g = 7'b1101_101;  // 2
			3: a_to_g = 7'b1111_001;  // 3
			4: a_to_g = 7'b0110_011;  // 4
			5: a_to_g = 7'b1011_011;  // 5
			6: a_to_g = 7'b1011_111;  // 6
			7: a_to_g = 7'b1110_000;  // 7
			8: a_to_g = 7'b1111_111;  // 8
			9: a_to_g = 7'b1111_011;  // 9
			10: a_to_g = 7'b1110_111;  // A
			11: a_to_g = 7'b0011_111;  // b
			12: a_to_g = 7'b0001_101;  // c
			13: a_to_g = 7'b0111_101;  // d
			14: a_to_g = 7'b1001_111;  // E
			15: a_to_g = 7'b1000_111;  // F
 			default: a_to_g = 7'b1111_110;
		endcase
	end

	always @(posedge clk) begin
		an = 4'b0000;
		an[s] = 1'b1;	
	end

	always @(posedge clk) begin
		if (clr) begin
			clkdiv <= 0;
		end
		
		else begin
			clkdiv <= clkdiv + 1;
		end
	end

endmodule

Testbench:

`timescale 1ns / 1ps

module TB_GCD();

    reg clk,clr,go,wea,addra;
    reg [7:0] dina;
    wire [7:0] gcd;
    wire [7:0] douta;
    reg xsig,ysig;
    
    GCD_Top uut(
    .clk(clk),
    .clr(clr),
    .go(go),
    .gcd(gcd),
    .xsig(xsig),
    .ysig(ysig),
    .wea(wea),
    .addra(addra),
    .dina(dina),
    .douta(douta)
    );
    
    always begin
    #10 clk = ~clk;
    end
    
    initial begin
    clk = 1'b1;
    clr = 1'b1;
    go = 1'b0;
    xsig = 1'b0;
    ysig = 1'b0;
    dina = 8'b00000000;
    wea = 1'b0;
    addra = 1'b0;
    
    #30 clr = 1'b0;
    
    #30 wea = 1'b1;
    dina = 8'b00001111;
    
    #30 wea = 1'b0;
    
    #30 xsig = 1'b1;
    
    #30 xsig = 1'b0;
    
    #30 wea = 1'b1;
    dina = 8'b01011101;
    addra = 1'b1;
          
    #30 wea = 1'b0;
        
    #30 ysig = 1'b1;
        
    #30 ysig = 1'b0;
    
    #30 go = 1'b1;
    
    end
    
endmodule

管脚分配(I/O Ports)文件:

开发板型号:Xilinx Artix7 EGO1(如封面图)

set_property IOSTANDARD LVCMOS33 [get_ports {dina[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dina[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {douta[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports addra]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports wea]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {a_to_g[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gcd[0]}]
set_property PACKAGE_PIN P17 [get_ports clk]
set_property PACKAGE_PIN R15 [get_ports clr]
set_property PACKAGE_PIN U3 [get_ports go]
set_property PACKAGE_PIN V2 [get_ports wea]
set_property PACKAGE_PIN V5 [get_ports xsig]
set_property PACKAGE_PIN V4 [get_ports ysig]
set_property PACKAGE_PIN P5 [get_ports {dina[7]}]
set_property PACKAGE_PIN P4 [get_ports {dina[6]}]
set_property PACKAGE_PIN P3 [get_ports {dina[5]}]
set_property PACKAGE_PIN P2 [get_ports {dina[4]}]
set_property PACKAGE_PIN R2 [get_ports {dina[3]}]
set_property PACKAGE_PIN M4 [get_ports {dina[2]}]
set_property PACKAGE_PIN N4 [get_ports {dina[1]}]
set_property PACKAGE_PIN R1 [get_ports {dina[0]}]
set_property PACKAGE_PIN F6 [get_ports {douta[7]}]
set_property PACKAGE_PIN G4 [get_ports {douta[6]}]
set_property PACKAGE_PIN G3 [get_ports {douta[5]}]
set_property PACKAGE_PIN J4 [get_ports {douta[4]}]
set_property PACKAGE_PIN H4 [get_ports {douta[3]}]
set_property PACKAGE_PIN J3 [get_ports {douta[2]}]
set_property PACKAGE_PIN J2 [get_ports {douta[1]}]
set_property PACKAGE_PIN K2 [get_ports {douta[0]}]
set_property PACKAGE_PIN K1 [get_ports {gcd[7]}]
set_property PACKAGE_PIN H6 [get_ports {gcd[6]}]
set_property PACKAGE_PIN H5 [get_ports {gcd[5]}]
set_property PACKAGE_PIN J5 [get_ports {gcd[4]}]
set_property PACKAGE_PIN K6 [get_ports {gcd[3]}]
set_property PACKAGE_PIN L1 [get_ports {gcd[2]}]
set_property PACKAGE_PIN M1 [get_ports {gcd[1]}]
set_property PACKAGE_PIN K3 [get_ports {gcd[0]}]
set_property PACKAGE_PIN T5 [get_ports addra]
set_property PACKAGE_PIN D4 [get_ports {a_to_g[6]}]
set_property PACKAGE_PIN E3 [get_ports {a_to_g[5]}]
set_property PACKAGE_PIN D3 [get_ports {a_to_g[4]}]
set_property PACKAGE_PIN F4 [get_ports {a_to_g[3]}]
set_property PACKAGE_PIN F3 [get_ports {a_to_g[2]}]
set_property PACKAGE_PIN E2 [get_ports {a_to_g[1]}]
set_property PACKAGE_PIN D2 [get_ports {a_to_g[0]}]
set_property PACKAGE_PIN G1 [get_ports {an[3]}]
set_property PACKAGE_PIN F1 [get_ports {an[2]}]
set_property PACKAGE_PIN E1 [get_ports {an[1]}]
set_property PACKAGE_PIN G6 [get_ports {an[0]}]

运行结果示例:

Synthesis RTL

2b96443042c0f921e46dc237b14b7bc5.png

Testbench:

598dc8c501ade585c6f2bb87f4e3cbbf.png
分别输入15和93,GCD输出3

仿真通过。

Bord Verification:

5474f9d4ea9baa112e3c918110a5db69.png
给x输入57的二进制数

4a6d44484b4ec4b70a446c4898ad04cd.png
给y输入12的二进制数

bff75dc6890734935dad4c073a18c967.png
按下go开关,显示数字3

板级验证通过。

Thanks for your reading.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值