我使用xilinx在VHDL中编写了80c51架构。为了提高时钟频率,我已将所有80c51指令流水线化。指令能够根据需要执行,例如。当第一条指令被处理时,第二条指令被取出。
然而,尽管从综合报告中创建了3的流水线深度,但我的时钟频率略高(约+/- 10Hz)。我发现瓶颈是由于综合报告指定的一个操作,但我无法理解综合报告。
请问从'SEQ / decode_3到SEQ / i_ram_addr_7'试图做什么是数据路径? (根据我的猜测,我推断使用一个案例,当声明检查100+相关操作码但不确定这是否是瓶颈。但我无能为力)
因此,我只有两个查询:
首先,流水线操作是否可能不会增加时钟频率,而测试平台是解释时序减少的唯一方法?
其次,我怎样才能推断出我的代码中哪条路径是'SEQ / decode_3到SEQ / i_ram_addr_7'的瓶颈。
感谢所有能帮助解释我疑虑的人!
Timing Summary:
---------------
Speed Grade: -4
Minimum period: 12.542ns (Maximum Frequency: 79.730MHz)
Minimum input arrival time before clock: 10.501ns
Maximum output required time after clock: 5.698ns
Maximum combinational path delay: No path found
Timing Detail:
--------------
All values displayed in nanoseconds (ns)
=========================================================================
Timing constraint: Default period analysis for Clock 'clk'
Clock period: 12.542ns (frequency: 79.730MHz)
Total number of paths / destination ports: 113114 / 2670
-------------------------------------------------------------------------
Delay: 12.542ns (Levels of Logic = 10)
Source: SEQ/decode_3 (FF)
Destination: SEQ/i_ram_addr_7 (FF)
Source Clock: clk rising
Destination Clock: clk rising
Data Path: SEQ/decode_3 to SEQ/i_ram_addr_7
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
FDC:C->Q 102 0.591 1.364 SEQ/decode_3 (SEQ/decode_3)
LUT4_D:I1->O 10 0.643 0.885 SEQ/de_state_cmp_eq002111 (N314)
LUT4:I3->O 7 0.648 0.740 SEQ/de_state_cmp_eq00711 (SEQ/de_state_cmp_eq0071)
LUT4:I2->O 3 0.648 0.534 SEQ/i_ram_addr_mux0000<0>11111 (N2301)
LUT4:I3->O 1 0.648 0.000 SEQ/i_ram_addr_mux0000<0>11270_SW0_SW0_F (N1284)
MUXF5:I0->O 1 0.276 0.423 SEQ/i_ram_addr_mux0000<0>11270_SW0_SW0 (N955)
LUT4_D:I3->O 6 0.648 0.701 SEQ/i_ram_addr_mux0000<0>11270 (SEQ/i_ram_addr_mux0000<0>11270)
LUT3_L:I2->LO 1 0.648 0.103 SEQ/i_ram_addr_mux0000<7>221_SW2_SW0 (N1208)
LUT4:I3->O 1 0.648 0.423 SEQ/i_ram_addr_mux0000<7>351_SW1 (N1085)
LUT4:I3->O 1 0.648 0.423 SEQ/i_ram_addr_mux0000<7>2 (SEQ/i_ram_addr_mux0000<7>2)
LUT4:I3->O 1 0.648 0.000 SEQ/i_ram_addr_mux0000<7>167 (SEQ/i_ram_addr_mux0000<7>)
FDE:D 0.252 SEQ/i_ram_addr_7
----------------------------------------
Total 12.542ns (6.946ns logic, 5.596ns route)
(55.4% logic, 44.6% route)
=========================================================================
Timing constraint: Default OFFSET IN BEFORE for Clock 'clk'
Total number of paths / destination ports: 154 / 154
-------------------------------------------------------------------------
Offset: 8.946ns (Levels of Logic = 6)
Source: rst (PAD)
Destination: SEQ/i_ram_diByte_1 (FF)
Destination Clock: clk rising
Data Path: rst to SEQ/i_ram_diByte_1
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
IBUF:I->O 444 0.849 1.392 rst_IBUF (REG/ext_int/fd_out1_0__or0000)
BUF:I->O 445 0.648 1.425 rst_IBUF_1 (rst_IBUF_1)
LUT3:I2->O 4 0.648 0.730 ROM/data<1>1 (i_rom_data<1>)
LUT4:I0->O 1 0.648 0.500 SEQ/i_ram_diByte_mux0000<1>17_SW0 (N1262)
LUT4:I1->O 1 0.643 0.563 SEQ/i_ram_diByte_mux0000<1>32 (SEQ/i_ram_diByte_mux0000<1>32)
LUT4:I0->O 1 0.648 0.000 SEQ/i_ram_diByte_mux0000<1>60 (SEQ/i_ram_diByte_mux0000<1>)
FDE:D 0.252 SEQ/i_ram_diByte_1
----------------------------------------
Total 8.946ns (4.336ns logic, 4.610ns route)
(48.5% logic, 51.5% route)
=========================================================================
为了让我更具有特定性,我将在1个操作码的解码阶段给出一个示例代码的snipplet。
以下是解码opdcode时的1种情况,opdcode是mov指令。大约有100多个操作码(100多个指令),这意味着这个case语句有超过100个语句。
案例OPCODE
- MOV A,Rn
时
当“11101000”| “11101001”| “11101010”| “11101011”| “11101100”| “11101101”| “11101110”| “11101111”=&gt; case de_state是 当E7 =&gt;de_state <= E8; when E8 => de_state <= E9; when E9 => de_state <= E10; when E10 => --Draw PSW i_ram_addr <= xD0; i_ram_rdByte <= '1'; de_state <= E11; when E11 => --Draw from Rn i_ram_addr <= "000" & i_ram_doByte(4 downto 3)& opcode(2 downto 0); i_ram_rdByte <= '1'; de_state <= E12; when E12 => --Place into EDR EDR <= i_ram_doByte; --close rdByte i_ram_rdByte <= '0'; when others => end case;
我希望你能更好地了解我的vhdl代码。我将不胜感激任何形式的帮助。谢谢!
答案 0 :(得分:1)
既然您正在使用Xilinx,我认为您还可以访问PlanAhead吗?尝试“分析时间/平面布置设计(PlanAhead)”(在“实施设计” - >“放置和路线”下)。
PlanAhead应该打开,并在底部为您提供时间结果的视图。选择关键路径(具有最小松弛的路径),右键单击它并选择“原理图”,这将显示所涉及原语的图形视图。然后,您可以右键单击基元并选择“Expand Cone” - &gt; “To Flops”也可以查看周围的组件。
这可以帮助您更好地了解所涉及的信号。尝试将输入和输出信号跟踪到VHDL代码,并专注于该路径以进行优化。
答案 1 :(得分:1)
这些信息不会有好的答案;我们只能猜测是什么源代码生成了这个硬件。
但很明显,您需要检查来源,做出假设缓慢的原因,采取措施纠正问题,并测试解决方案。
重复直到足够快。
我的猜测,鉴于你的暗示有一个案例陈述来解码操作码......
其中一个武器就像:
when <some expression involving decode> =>
address <= <some address calculation>;
问题在于两个表达式通常是相互关联的,因此它们在同一个循环中进行评估。一个示例解决方案是将地址表达式(即在前一个周期中)预先计算到寄存器中,并将case arm重写为:
when <some expression involving decode> =>
address <= register;
如果您猜对了,结果会稍快一些,并且您还有另一个(类似的)瓶颈需要修复。重复直到足够快......
但如果没有来源和时间分析,不要指望更具体的答案。
编辑:发布了一小部分源代码后,图片更加清晰: 你有两个嵌套的Case语句,每个语句都很大。你显然需要一些简化......我注意到只有2个内壳臂分配给i_ram_addr,但时序分析显示了i_ram_addr上庞大而复杂的多路复用器;显然,还有很多其他案例武器为i_ram_addr提供了条款......
我建议您可能必须将i_ram_addr与主Case语句分开处理,并编写最简单的机器来单独生成i_ram_addr。 例如,我会注意到OPCODE案例组等同于:
if OPCODE(7 downto 3) = "11101" then ...
并询问单独为i_ram_addr获取解码器有多简单。 您可能会发现许多其他案例武器与i_ram_addr做了非常类似的事情(最初的8051设计师会抓住机会简化逻辑!)。 合成工具在简化逻辑方面非常聪明,但是当事情变得太复杂时,它们可能会错失机会。
(在这个阶段我会注释掉i_ram_addr的分配并留下解码器的其余部分)