原创 Verilog和FPGA建模学习心得(2)

2012-12-31 02:05 2786 17 17 分类: FPGA/CPLD 文集: Verilog

昨晚熬到2点,最后ARAM和NIOS ii 都指向了LED,“她”亮了,自己该研究别的了,今天做起了Modelsim的仿真,就那乘法算法来开刀,一天的算法研究让自己不仅对算法有了小小的认识,同时对建模也有了更进一步的了解,就代码和总结写到这儿,一点总结,一点积累…

module Multipiler_Module(
         Clk_50m,
         Rst_n,
         StartSig,
         Multiplicand,
         Multiplier,
         DoneSig,
         Product
         );
input Clk_50m;
input Rst_n;
input StartSig;
input [7:0]Multiplicand;
input [7:0]Multiplier;

output DoneSig;
output [15:0] Product;

reg [1:0] i_Count;
reg isNeg;
reg [7:0] Mcand;
reg [7:0] Mer;
reg [15:0] Temp;
reg isDone;

always @ (posedge Clk_50m or negedge Rst_n) begin
 if(!Rst_n) begin
  i_Count <= 2'b0;
  isNeg   <= 1'b0;
  Mcand   <= 8'd0;
  Mer     <= 8'd0;
  Temp    <= 16'd0;
  isDone  <= 1'b0;
 end
 else if(StartSig)
  case (i_Count)
   0: begin
    isNeg <= Multiplicand[7] ^ Multiplier[7];
    Mcand <= isNeg ? (~ Multiplicand + 1'b1) : Multiplicand;
    Mer   <= isNeg ? (~ Multiplier + 1'b1) : Multiplier;
    Temp  <= 16'd0;
    i_Count <= i_Count + 1'b1;
   end //end case 0
   1: if(Mer == 1'b0) i_Count = i_Count + 1'b1;
    else begin
     Temp <= Temp + Mcand;
     Mer  <= Mer - 1'b1;
    end //end of case 1
   2: begin isDone <= 1'b1; i_Count <= i_Count + 1'b1; end
   3: begin isDone <= 1'b0; i_Count <= 2'd0; end
  endcase
end

assign DoneSig = isDone;
assign Product = isNeg ? (~Temp + 1'b1) : Temp;

endmodule

下面是费了很大劲写成的Test Bench!!!

 

`timescale 1 ns/ 1 ps
module Multipiler_Module_vlg_tst();
reg Clk_50m;
reg [7:0] Multiplicand;
reg [7:0] Multiplier;
reg Rst_n;
reg StartSig;
// wires                                              
wire DoneSig;
wire [15:0]  Product;
                        
Multipiler_Module i1 (
 .Clk_50m(Clk_50m),
 .DoneSig(DoneSig),
 .Multiplicand(Multiplicand),
 .Multiplier(Multiplier),
 .Product(Product),
 .Rst_n(Rst_n),
 .StartSig(StartSig)
);
initial                                               
begin
 Rst_n = 0; #100; Rst_n = 1;
 Clk_50m = 0; forever #10 Clk_50m =~ Clk_50m;
end  
/* ************************************************************************* */
reg [3:0] j_Count;

always @ (posedge Clk_50m or negedge Rst_n) begin
 if(!Rst_n) begin
  j_Count <= 4'd0;
  StartSig <= 1'b0;
  Multiplicand <= 8'd0;
  Multiplier   <= 8'd0;
 end
 else case (j_Count)
  0: if(DoneSig) begin StartSig <= 1'b0; j_Count = j_Count + 1'b1; end
   else begin Multiplicand <= 8'd3; Multiplier <= 8'd20; StartSig <= 1'b1; end
  1: if(DoneSig) begin StartSig <= 1'b0; j_Count = j_Count + 1'b1; end
   else begin Multiplicand <= 8'd40; Multiplier <= 8'd5; StartSig <= 1'b1; end
  2: if(DoneSig) begin StartSig <= 1'b0; j_Count = j_Count + 1'b1; end
   //Multiplier   <= 8'b10101010(-42)
   else begin Multiplicand <= 8'd3; Multiplier <= 8'b10101010; StartSig <= 1'b1; end
  3: if(DoneSig) begin StartSig <= 1'b0; j_Count = j_Count + 1'b1; end
   //Multiplicand <= 8'b11001100(-76)
   else begin Multiplicand <= 8'b11001100; Multiplier <= 8'd4; StartSig <= 1'b1; end
  4: if(DoneSig) begin StartSig <= 1'b0; j_Count = j_Count + 1'b1; end
   else begin Multiplicand <= 8'b11001100; Multiplier <= 8'b10101010; StartSig <= 1'b1; end
  5: j_Count <= 4'd5;
 endcase
end
                                                                                              
endmodule

之后是其波形:20121231015311821001.png

最后就小总结吧:

1.乘法->判断大小->Booth乘法->P空间。

2.“<=”时间沿有效地赋值,以时间点的过去为判断标准。

3.“=”以即时结果为判断标准,会破坏“时间点”的和谐性!

4.取值(正、负):A <= A[7] ? ( ~A + 1'b1) : A;

5.两个数运算的符号(正、负):isNeg <= A[7] ^ B[7];

6.A - B <= A + ( ~B + 1'B1);

最后的最后:建模一定是一个模块一个功能!!!

文章评论0条评论)

登录后参与讨论
我要评论
0
17
关闭 站长推荐上一条 /2 下一条