最晚为了总结逝去的2012,一直写到2点半,今天虽然是新年,可自己还是那个学习建模的自己,因为爸爸时常说:富人过年,穷人过难。
看看今天的建模:LUT.
module Lut_Multiplier_module(
input Clk_50m,
input Rst_n,
input StartSig,
input [7:0]A,
input [7:0]B,
output DoneSig,
output [15:0]Product,
output [8:0]QoutI1Sig,
output [8:0]QoutI2Sig,
output [15:0]QoutPro1Sig,
output [15:0]QoutPro2Sig
);
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
wire [15:0] Q1Sig_w;
wire [15:0] Q2Sig_w;
reg [8:0] QoutI1Sig_r;
reg [8:0] QoutI2Sig_r;
reg isDoneSig_r;
reg [15:0] Product_r;
reg [2:0] i_Count;
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n) begin
i_Count <= 3'd0;
QoutI1Sig_r <= 9'd0;
QoutI2Sig_r <= 9'd0;
isDoneSig_r <= 1'b1;
i_Count <= 3'd0;
Product_r <= 16'd0;
end
else if(StartSig)
case (i_Count)
0: begin
QoutI1Sig_r <= {A[7],A} + {B[7],B};
QoutI2Sig_r <= {A[7],A} + {~B[7],(~B + 1'b1)};
i_Count <= i_Count + 1'b1;
end
1: begin
QoutI1Sig_r <= QoutI1Sig_r[7]? (~QoutI1Sig_r + 1'b1): QoutI1Sig_r;
QoutI2Sig_r <= QoutI2Sig_r[7]? (~QoutI2Sig_r + 1'b1): QoutI2Sig_r;
i_Count <= i_Count + 1'b1;
end
2: begin
i_Count <= i_Count + 1'b1;
end
3: begin
Product_r <= Q1Sig_w + (~Q2Sig_w + 1'b1);
i_Count <= i_Count + 1'b1;
end
4: begin
isDoneSig_r <= 1'b1;
i_Count <= i_Count + 1'b1;
end
5: begin
isDoneSig_r <= 1'b0;
i_Count <= 3'd0;
end
endcase
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
Lut_module U1(
.Clk_50m(Clk_50m),
.Rst_n(Rst_n),
.Addr(QoutI1Sig_r[7:0]),
.Qout(Q1Sig_w)
);
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
Lut_module U2(
.Clk_50m(Clk_50m),
.Rst_n(Rst_n),
.Addr(QoutI2Sig_r[7:0]),
.Qout(Q2Sig_w)
);
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
assign DoneSig = isDoneSig_r;
assign Product = Product_r;
assign QoutI1Sig = QoutI1Sig_r;
assign QoutI2Sig = QoutI2Sig_r;
assign QoutPro1Sig = Q1Sig_w;
assign QoutPro2Sig = Q2Sig_w;
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
endmodule
有点长,慢慢看吧。
module Lut_module(
Clk_50m,
Rst_n,
Addr,
Qout
);
input Clk_50m;
input Rst_n;
input [7:0] Addr;
output [15:0] Qout;
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
reg [15:0] Qout_r;
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
Qout_r <= 16'd0;
else case (Addr)
0,1: Qout_r <= 16'd0;
2: Qout_r <= 16'd1;
此处省略好多值,慢慢算……
255 : Qout_r <= 16'd16256;
endcase
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
assign Qout = Qout_r;
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
endmodule
最后看看Test Bench
`timescale 1 ns/ 1 ps
module Lut_Multiplier_module_vlg_tst();
reg [7:0] A;
reg [7:0] B;
reg Clk_50m;
reg Rst_n;
reg StartSig;
// wires
wire DoneSig;
wire [15:0] Product;
wire [8:0] QoutI1Sig;
wire [8:0] QoutI2Sig;
wire [15:0] QoutPro1Sig;
wire [15:0] QoutPro2Sig;
// assign statements (if any)
Lut_Multiplier_module i1 (
// port map - connection between master ports and signals/registers
.A(A),
.B(B),
.Clk_50m(Clk_50m),
.DoneSig(DoneSig),
.Product(Product),
.QoutI1Sig(QoutI1Sig),
.QoutI2Sig(QoutI2Sig),
.QoutPro1Sig(QoutPro1Sig),
.QoutPro2Sig(QoutPro2Sig),
.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 [2:0] j_Count;
always @ (posedge Clk_50m or negedge Rst_n) begin
if(!Rst_n) begin
j_Count <= 3'd0;
A <= 8'd0;
B <= 8'd0;
StartSig <= 1'b0;
$write("Simulation reset of Successful!\n");
end
else case (j_Count)
0: if(DoneSig) begin StartSig <= 1'b0; j_Count <= j_Count + 1'b1;
$write("Simulation of else Successful!\n"); end
else begin A <= 8'b10000001; B <= 8'b01111111; StartSig <= 1'b1; end
//else begin A <= 8'd3; B <= 8'd5; StartSig <= 1'b1; Rst_n = 0; #200; Rst_n = 1;
// $write("Simulation of else'else Successful!\n"); end
//-127 * 127
1: if(DoneSig) begin StartSig <= 1'b0; j_Count <= j_Count + 1'b1; end
else begin A <= 8'b11111100; B <= 8'b00001111; StartSig <= 1'b1; end
//-4 * 15
2: if(DoneSig) begin StartSig <= 1'b0; j_Count <= j_Count + 1'b1; end
else begin A <= 8'b01100100; B <= 8'b01000010; StartSig <= 1'b1; end
//100 * 66
3: if(DoneSig) begin StartSig <= 1'b0; j_Count <= j_Count + 1'b1; end
else begin A <= 8'b11011101; B <= 8'b11101000; StartSig <= 1'b1; end
//-35 * -24 (-杜兰特 * -科比,呵呵)
4: j_Count <= 3'd4;
//累了就停下来吧!
endcase
end
endmodule
就这样,该写的写完了,一运行Modelsim,什么都没有,多么漂亮的代码,为什么啥都没?????叽咕中…
那么开始数小时的调试:
1.看了看有时钟,没有复位,原来自己写的是:Rst_n = 1; #100; Rst_n = 1;
2.j_Count有变化,A/B没值,这就怪了,说明case中的if执行了,else没有执行,加了一句$write("Simulation of else Successful!\n"); 果然是,说明DoneSig一直为高电平,一看Lut_Multiplier_module的初始化,是、是、是isDoneSig_r <= 1'b1;那么改成isDoneSig_r <= 1'b0;试试看,见证奇迹的时候到了,一运行,\(^o^)/
代码是长了点,但有用的不多,原理就是:ab = ( ( a + b )2 )/4 - ( ( a - b )2 )/4
居然发现不复位不行,复位了,马虎也不行,也就是我没执行,你居然谎报军情,说我执行了,那我就给你不好好执行!!!
用户403664 2013-1-4 15:36