Xilinx FPGA 乘法器IP设计实验的问题
FPGA是Virtex-5的,实验手册上的代码是:
reg [0:C_SLV_DWIDTH-1] tmp_reg;
always @(posedgeBus2IP_Clk)
begin
if(Bus2IP_Reset==1)
begin
slv_reg2<=0;
tmp_reg<=0;
end
else
begin
tmp_reg<=slv_reg0*slv_reg1; //为什么要用tmp_reg来在这里插入一个时钟周期?
slv_reg2<=tmp_reg;
end
end
而且思考题就是“tmp_reg”的目的是什么?
我猜是不是FPGA的verilog星号综合后的乘法器必须2个周期才算出正确结果?
如果是的话,即使删掉这句话,语法也对啊,大不了结果不正确呗,软件工具为什么如此智能吗?
我一头雾水。恳请大侠指点。
多谢回帖。
这两天是服务器连不上去了。机房施工。所以warning提示我现在贴不出来。
好像是有delay和component这两个词。
我感觉不是语法问题,因为思考题就是:
What is the purpose of the tmp_reg from the Verilog code provided in lab?
(另外,编完Verilog之后我们还要写一个C代码来向自定义IP中写数,和读数。感觉没有关系,因为写C是写完Verilog之后的事)
module user_logic
(
// -- ADDUSER PORTS BELOW THIS LINE ---------------
// --USERports added here
// -- ADDUSER PORTS ABOVE THIS LINE ---------------
// -- DO NOTEDIT BELOW THIS LINE ------------------
// -- Busprotocol ports, do not add to or delete
Bus2IP_Clk,
// Bus to IP clock
Bus2IP_Reset,
//Bus to IP reset
Bus2IP_Data,
//Bus to IP data bus
Bus2IP_BE,
//Bus to IP byte enables
Bus2IP_RdCE,
//Bus to IP read chip enable
Bus2IP_WrCE,
//Bus to IP write chip enable
IP2Bus_Data,
//IP to Bus data bus
IP2Bus_RdAck,
//IP to Bus read transfer acknowledgement
IP2Bus_WrAck,
//IP to Bus write transfer acknowledgement
IP2Bus_Error
//IP to Bus error response
// -- DO NOTEDIT ABOVE THIS LINE ------------------
); // user_logic
// -- ADD USER PARAMETERS BELOW THIS LINE ------------
// --USER parameters added here
// -- ADD USER PARAMETERS ABOVE THIS LINE------------
// -- DO NOT EDIT BELOW THIS LINE--------------------
// -- Bus protocol parameters, do not add to ordelete
parameter C_SLV_DWIDTH
= 32;
parameter C_NUM_REG
= 3;
// -- DO NOT EDIT ABOVE THIS LINE--------------------
// -- ADD USER PORTS BELOW THIS LINE-----------------
// --USER ports added here
// -- ADD USER PORTS ABOVE THIS LINE-----------------
// -- DO NOT EDIT BELOW THIS LINE--------------------
// -- Bus protocol ports, do not add to or delete
input
Bus2IP_Clk;
input
Bus2IP_Reset;
input
[0: C_SLV_DWIDTH-1]
Bus2IP_Data;
input
[0: C_SLV_DWIDTH/8-1]
Bus2IP_BE;
input
[0: C_NUM_REG-1]
Bus2IP_RdCE;
input
[0: C_NUM_REG-1]
Bus2IP_WrCE;
output
[0: C_SLV_DWIDTH-1]
IP2Bus_Data;
output
IP2Bus_RdAck;
output
IP2Bus_WrAck;
output
IP2Bus_Error;
// -- DO NOT EDIT ABOVE THIS LINE--------------------
//----------------------------------------------------------------------------
// Implementation
//----------------------------------------------------------------------------
// --USERnets declarations added here, as needed for user logic
// Nets foruser logic slave model s/w accessible register example
reg
[0 : C_SLV_DWIDTH-1]
slv_reg0;
reg
[0 : C_SLV_DWIDTH-1]
slv_reg1;
reg
[0 : C_SLV_DWIDTH-1]
slv_reg2;
wire
[0 : 2]
slv_reg_write_sel;
wire
[0: 2]
slv_reg_read_sel;
reg
[0 : C_SLV_DWIDTH-1]
slv_ip2bus_data;
wire
slv_read_ack;
wire
slv_write_ack;
integer
byte_index, bit_index;
// --USERlogic implementation added here
always@(posedge Bus2IP_Clk)
begin
if(Bus2IP_Reset==1)
begin
slv_reg2<=0;
end
else
begin
slv_reg2<=slv_reg0*slv_reg1;
end
end
//------------------------------------------------------
// Examplecode to read/write user logic slave model s/w accessible registers
//
// Note:
// Theexample code presented here is to show you one way of reading/writing
// softwareaccessible registers implemented in the user logic slave model.
// Each bitof the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
// to onesoftware accessible register by the top level template. For example,
// if youhave four 32 bit software accessible registers in the user logic,
// you arebasically operating on the following memory mapped registers:
//
//
Bus2IP_WrCE/Bus2IP_RdCE
Memory Mapped Register
//
"1000"
C_BASEADDR + 0x0
//
"0100"
C_BASEADDR + 0x4
//
"0010"
C_BASEADDR + 0x8
//
"0001"
C_BASEADDR + 0xC
//
// ------------------------------------------------------
assign
slv_reg_write_sel = Bus2IP_WrCE[0:2],
slv_reg_read_sel
=Bus2IP_RdCE[0:2],
slv_write_ack
= Bus2IP_WrCE[0]|| Bus2IP_WrCE[1] || Bus2IP_WrCE[2],
slv_read_ack
= Bus2IP_RdCE[0]|| Bus2IP_RdCE[1] || Bus2IP_RdCE[2];
// implementslave model register(s)
always @(posedge Bus2IP_Clk )
begin:SLAVE_REG_WRITE_PROC
if (Bus2IP_Reset == 1 )
begin
slv_reg0 <= 0;
slv_reg1 <= 0;
//slv_reg2<= 0;
end
else
case (slv_reg_write_sel )
3'b100 :
for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index =byte_index+1 )
if ( Bus2IP_BE[byte_index] == 1 )
for ( bit_index = byte_index*8;bit_index <= byte_index*8+7; bit_index = bit_index+1 )
slv_reg0[bit_index] <= Bus2IP_Data[bit_index];
3'b010 :
for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index =byte_index+1 )
if ( Bus2IP_BE[byte_index] == 1 )
for ( bit_index = byte_index*8; bit_index <= byte_index*8+7;bit_index = bit_index+1 )
slv_reg1[bit_index] <= Bus2IP_Data[bit_index];
default : ;
endcase
end //SLAVE_REG_WRITE_PROC
// implementslave model register read mux
always @(slv_reg_read_sel or slv_reg0 or slv_reg1 or slv_reg2 )
begin:SLAVE_REG_READ_PROC
case (slv_reg_read_sel )
3'b100: slv_ip2bus_data <= slv_reg0;
3'b010: slv_ip2bus_data <= slv_reg1;
3'b001: slv_ip2bus_data <= slv_reg2;
default : slv_ip2bus_data <= 0;
endcase
end //SLAVE_REG_READ_PROC
//------------------------------------------------------------
// Examplecode to drive IP to Bus signals
//------------------------------------------------------------
assignIP2Bus_Data
= slv_ip2bus_data;
assignIP2Bus_WrAck
= slv_write_ack;
assignIP2Bus_RdAck
= slv_read_ack;
assign IP2Bus_Error
= 0;
endmodule
呵呵呵呵呵学习了
这个地方ise应该会把它综合成DSP,不知道一拍 能不能出结果,两拍到三拍应该是没有问题的。
这个地方如果没有延迟,是不是就不能做优化。
不觉得需到那个中间变量。除了加一个时钟的延时,不会有任何用处。有一个可能是C_SLV_DWIDTH如果非常大,那么一个乘法器需要多个DSP48来实现,可能需要用到工具的retiming,这时候,这个中间变量会有帮助。
小编,我也在做这个实验,没搞明白这个问题。求帮助阿
