|  | 
 
| 
用Verilog实现,两个16位输入,一个32位输出的四则运算模块,这里我是使用的调用IP核的方式,毕竟人家官方推出的要比我们自个写的要稳定一点,这里调用了加法器,减法器,乘法器,触发器的IP核。
×
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册  
 代码如下:
 
 module jisuan(
 //input pin;
 Clk,
 Rst_n,
 data_A,
 data_B,
 mode, //+,-,*,/.
 start,
 //output pin;
 data_C
 
 );
 //input pin define;
 input Clk;
 input Rst_n;
 input [1 : 0]mode;
 input [15 : 0]data_A;
 input [15 : 0]data_B;
 input start;
 //output pin define;
 output reg[31 : 0]data_C;
 
 localparam
 add = 2'b00,
 min = 2'b01,
 mul = 2'b10,
 did = 2'b11;
 
 wire [15 : 0]result1;
 wire [15 : 0]result2;
 wire [31 : 0]result3;
 reg add_sub;
 wire cout;
 reg clken_subormin;
 reg clken_chufa;
 reg clken_chengfa;
 reg aclr;
 
 subormin subormin1(
 .aclr(aclr),
 .add_sub(add_sub),
 .clken(clken_subormin),
 .clock(Clk),
 .dataa(data_A),
 .datab(data_B),
 .result(result1)
 );
 
 chufa chufa1(
 .aclr(aclr),
 .clken(clken_chufa),
 .clock(Clk),
 .denom(data_B),
 .numer(data_A),
 .quotient(result2),
 .remain()
 );
 
 chengfa chengfa1(
 .aclr(aclr),
 .clken(clken_chengfa),
 .clock(Clk),
 .dataa(data_A),
 .datab(data_B),
 .result(result3)
 );
 
 always@(posedge Clk or negedge Rst_n)
 if(!Rst_n)begin
 clken_subormin <= 1'b0;
 clken_chengfa <= 1'b0;
 clken_chufa <= 1'b0;
 add_sub <= 1'b0;
 aclr <= 1'b1; //清零
 end
 else if(start) begin
 aclr <= 1'b0;
 
 case(mode)
 add : begin add_sub <= 1'b1; clken_subormin <= 1'b1; end
 min : begin add_sub <= 1'b0; clken_subormin <= 1'b1; end
 mul : clken_chengfa <= 1'b1;
 did : clken_chufa <= 1'b1;
 default: ;
 endcase
 
 end
 else  begin
 clken_subormin <= 1'b0;
 clken_chengfa <= 1'b0;
 clken_chufa <= 1'b0;
 aclr <= 1'b1;
 end
 
 always@(posedge Clk or negedge Rst_n)
 if(!Rst_n)
 data_C <= 32'd0;
 else if(start)
 case(mode)
 add : data_C[15 : 0] <= result1;
 min : data_C[15 : 0] <= result1;
 did : data_C[15 : 0] <= result2;
 mul : data_C <= result3;
 default : data_C <= 32'd0;
 endcase
 else
 data_C <= 32'd0;
 
 endmodule
 
 模块使用方法:输入data_A,data_B,确定mode(加,减,乘,除),然后Start=1,开始进行计算,四个时钟周期后,data_C上的值就是运算结果。至于为什么要等待四个时钟周期呢,这是因为做运算是需要时间的吗,不可能刚给个输入数据,就直接可以得到输出数据。这个时间是怎么来的呢?通过仿真得来的,经过时序仿真,发现第四个时钟沿的时候数据是稳定的。
 
 仿真代码如下:
 
 `timescale 1ns / 1ns
 `define clk_period 20
 
 module jisuan_tb();
 
 //input pin define;
 reg Clk;
 reg Rst_n;
 reg [1 : 0]mode;
 reg [31 : 0]data_A;
 reg [31 : 0]data_B;
 reg start;
 //output pin define;
 wire [31 : 0]data_C;
 wire done;
 
 initial Clk = 1;
 always #(`clk_period / 2) Clk = ~Clk;
 
 jisuan u1(
 //input pin;
 .Clk(Clk),
 .Rst_n(Rst_n),
 .data_A(data_A),
 .data_B(data_B),
 .mode(mode), //+,-,*,/.
 .start(start),
 //output pin;
 .data_C(data_C)
 );
 
 initial begin
 mode = 0;
 Rst_n = 0;
 start = 0;
 #(20 * `clk_period);
 Rst_n = 1;
 #(20 * `clk_period);
 repeat(10)begin
 data_A = {$random} % 100;
 data_B = {$random} % 100;
 mode = mode + 1;
 start = 1;
 #(20 * `clk_period);
 start = 0;
 #(20 * `clk_period);
 end
 $stop;
 end
 
 
 endmodule
 
 
 这里还有个问题,就是这个IP核是怎么调用的呢?这个问题也困扰了我好久,有些IP核我们听都没听过,我们怎么知道什么时候可以用IP核,以及IP核的调用格式呢?这里我分享一个关于altera IP核的电子书:
 
 链接:https://pan.baidu.com/s/1P7y-ZCWhs0Ay6bLFZF3t5A
 提取码:k6js
 ————————————————
 版权声明:本文为CSDN博主「漫步人生只为寻你」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
 原文链接:https://blog.csdn.net/qq_37926592/article/details/86130514
 
 | 
 |