资讯动态

8 HDLBits —— CS450 芯片

发布时间:2026/8/19 13:03:48 来源:尧图企业网站定制
CS450 定时器实现一个定时器该定时器对给定的时钟周期数进行倒计数并在计数完成时断言一个信号以指示给定持续时间已结束。实现此功能的一种良好方式是使用递减计数器当计数值变为 0 时断言输出信号。每个时钟周期若 load 1则将内部计数器加载为 10 位数据 data该数据表示定时器在超时之前应计数的时钟周期数。计数器可在任意时刻加载包括仍在计数且尚未到达 0 时。若 load 0则内部计数器递减 1。输出信号 tc“terminal count”即终值计数指示内部计数器是否已达到 0。一旦内部计数器达到 0它应保持为 0停止计数直到计数器再次被加载。以下是要求定时器计数 3 个周期时的行为示例参考答案/* 模块功能带同步并行加载的10位递减倒计时计数器 核心逻辑 1. 时钟上升沿同步判定加载信号loadload有效则载入外部data数值无效则计数器非零时逐周期递减零时保持静止 2. tc为终端计数标志计数器归0时输出高电平其余时刻输出低电平 典型用途定时倒计时、脉冲周期控制、超时触发电路 */moduletop_module(input clk,// 系统时钟上升沿触发计数器状态更新input load,// 同步并行加载使能高电平有效优先级高于递减计数input[9:0]data,// 10位并行加载输入数据load拉高时写入计数器output tc// Terminal Count终端计数标志计数器为0时tc1);reg[9:0]counter;// 10位时序寄存器存储当前倒计时数值// 同步时序逻辑块仅时钟上升沿执行状态更新非阻塞赋值适配寄存器建模always (posedge clk)beginif(load)begin// 加载优先load有效同步载入外部给定数据覆盖原有计数值counterdata;endelsebegin// 加载无效倒计时模式数值非0则自减1数值为0保持不变停止递减if(counter!10d0)countercounter-1b1;end end// 纯组合逻辑连续赋值实时判定计数器是否归零输出终端标志tcassign tc(counter10d0);endmodule输出结果CS450 双二进制计数器分支方向预测器通常组织为计数器表由程序计数器PC和分支历史信息联合索引。每个表项通常采用两位状态因为单比特状态仅记录上一次预测结果缺乏足够的迟滞hysteresis特性导致状态翻转过于频繁。两位饱和计数器的状态图如下四个状态分别为强/弱 取TakenT和强/弱 不取Not-TakenNT一种效果良好的两位状态机是饱和计数器[1]该计数器可递增至 3即 2’b11或递减至 0即 2’b00但不会发生溢出回绕。“取”的结果使计数器加 1“不取”的结果使计数器减 1。当计数值为 2 或 3即 2’b1x时分支预测为“取”。加入一定迟滞可防止在强偏置的分支偶尔出现相反方向时预测值发生翻转因为此时需要在相反方向连续递增两次预测才会被翻转。参考文献R. Nair“最佳 2 位分支预测器”《IEEE 计算机汇刊》第 44 卷第 5 期1995 年 5 月。题目描述构建一个两位饱和计数器。当 train_valid 1 且 train_taken 1 时计数器递增最大到 3当 train_valid 1 且 train_taken 0 时计数器递减最小到 0。当不进行训练时train_valid 0计数器保持原值不变。areset 为异步复位信号将计数器复位为弱不取2’b01。输出 state[1:0] 为两位计数器的计数值。参考答案/* 模块功能2位饱和型分支预测状态机经典2bit饱和计数器分支预测器 核心机制 1. 高电平异步复位复位后强制进入状态2b01弱不预测跳转 2. 仅训练有效(train_valid1)时更新状态 - train_taken1实际发生跳转状态1上限饱和锁定2b11强预测跳转 - train_taken0实际不跳转状态-1下限饱和锁定2b00强预测不跳转 3. train_valid0无训练时状态保持不变内部寄存器直接对外输出当前2位状态 应用场景CPU流水线分支方向预测模块 */moduletop_module(input clk,// 工作时钟上升沿触发状态更新input areset,// 高电平异步复位优先级最高立刻复位无需等待时钟边沿input train_valid,// 训练有效使能高电平允许根据分支结果更新状态input train_taken,// 分支实际结果1跳转发生0未跳转output reg[1:0]state// 对外输出当前2bit预测状态);reg[1:0]state_reg;// 内部状态寄存变量保存饱和计数值// 时序逻辑异步高复位时钟上升沿状态更新非阻塞赋值适配寄存器always (posedge clk or posedge areset)beginif(areset)begin// 异步复位触发强制初始化为弱不跳转状态 01state_reg2b01;endelsebeginif(train_valid)begin// 训练有效按分支实际结果做饱和增减if(train_taken)begin// 分支跳转计数递增上限饱和到最大值11(3)不再增加if(state_reg2b11)state_regstate_reg1b1;endelsebegin// 分支不跳转计数递减下限饱和到最小值00(0)不再减小if(state_reg2b00)state_regstate_reg-1b1;end endelsebegin// 训练无效不更新状态保持原有计数值state_regstate_reg;end end end// 组合逻辑直通输出当前状态assign statestate_reg;endmodule输出结果CS450 历史移位寄存器分支方向预测器通常组织为计数器表由程序计数器PC和分支历史信息联合索引。分支历史是指最近若干分支的“取”或“不取”结果序列。在硬件实现中分支历史寄存器可实现为 N 位移位寄存器。在每个条件分支方向被预测后其预测方向被移入该移位寄存器。因此该移位寄存器保存了最近的 N 个分支结果。分支历史寄存器及其周边硬件。本练习构建的是蓝色虚线矩形内的分支历史寄存器。图中显示分支执行单元发出分支预测错误信号但根据处理器设计的不同该信号也可能在指令提交阶段或其他时刻发出。由于分支预测是推测性执行的流水线冲刷会带来额外的复杂性。当发生分支预测错误时处理器状态需要回滚到该错误预测分支之后的紧邻状态。这包括回滚全局历史寄存器其中可能包含了比该错误预测分支更年轻的分支所移入的预测结果但现在需要被丢弃。我们在此假设分支预测器外部存在硬件用于记住预测每个分支时所使用的分支历史寄存器状态并将其保存以供后续的分支预测器训练和流水线冲刷使用。当发生分支预测错误时该硬件通知分支预测器某个分支预测错误、该分支应有的实际方向、以及对应程序中该错误预测分支之前紧邻点的分支历史寄存器状态。当然由于处理器重新从该错误预测分支之后的点开始执行流水线冲刷后的分支历史寄存器需要追加该错误预测分支的实际方向。题目描述构建一个 32 位全局历史移位寄存器包括支持因分支预测错误导致的流水线冲刷而进行状态回滚。当进行分支预测时predict_valid 1从最低位侧移入 predict_taken以更新该预测分支的分支历史。predict_history[0] 表示最新分支的方向。当发生分支预测错误时train_mispredicted 1将分支历史寄存器加载为错误预测分支完成后的历史值。该值为错误预测分支之前的历史train_history与分支的实际结果train_taken拼接而成。若预测和预测错误同时发生则预测错误优先因为流水线冲刷也会将当前正在进行预测的分支冲刷掉。predict_history 是分支历史寄存器的当前值。areset 为异步复位信号将历史寄存器复位为零。参考答案/* 模块功能32位移位型分支历史寄存器CPU分支预测专用历史记录模块 核心逻辑分层优先级从高到低 1. 高电平异步复位立刻清空32位历史为全0无需等待时钟边沿 2. 预测错误修正预测出错时截取旧历史高31位拼接实际分支结果train_taken覆盖更新整体历史 3. 正常预测更新预测有效时原有历史左移1位、最低位补本次预测结果predict_taken实现历史滚动记录 4. 无有效操作历史值保持不变 输出直接对外暴露完整32位分支历史快照 */moduletop_module(input clk,// 系统时钟上升沿触发历史寄存器更新input areset,// 高电平异步全局复位优先级最高即时清零历史// 正常预测通路端口input predict_valid,// 本次预测有效标志高电平允许追加预测结果到历史末尾input predict_taken,// 本次预测的分支走向1预测跳转、0预测不跳转output[31:0]predict_history,// 实时对外输出完整32位分支历史寄存器值// 预测错误训练修正通路端口优先级高于正常预测input train_mispredicted,// 分支预测错误标志高电平触发历史回滚修正input train_taken,// 分支实际最终走向用于修正历史最低位input[31:0]train_history// 预测出错前保留的旧32位分支历史快照);reg[31:0]history;// 32位时序寄存器循环存储最近32次分支走向记录// 异步复位时钟上升沿时序逻辑非阻塞赋值适配寄存器建模always (posedge clk or posedge areset)beginif(areset)begin// 异步复位生效清空全部历史记录初始化为32位全0history32d0;endelseif(train_mispredicted)begin// 预测出错优先修正保留旧历史高31位最低位替换为真实分支结果// 语法{高位片段,最低位}拼接组合生成修正后的完整32位历史history{train_history[30:0],train_taken};endelseif(predict_valid)begin// 正常预测滚动更新旧历史左移1位丢弃最早记录最低位追加本次预测结果history{history[30:0],predict_taken};endelsebegin// 既无错误修正、也无有效预测历史值维持不变historyhistory;end end// 组合逻辑直通输出内部历史寄存器实时对外输出assign predict_historyhistory;endmodule输出结果CS450 全局共享分支预测器gshare 分支预测算法分支方向预测器分支方向预测器用于生成条件分支指令的“取”或“不取”方向预测。它位于处理器流水线的前端附近负责引导指令沿希望是正确的程序执行路径进行取指。分支方向预测器通常与分支目标缓冲器BTB配合使用其中BTB预测目标地址而方向预测器则决定是跳转到目标地址还是沿顺序路径继续取指。在流水线的稍后阶段通常在分支执行或提交阶段已执行分支指令的结果会被反馈回分支预测器以通过观察过往分支行为来训练其更准确地预测未来分支。当发生分支预测错误时也可能触发流水线冲刷。取指阶段内的分支方向预测器。该分支预测器借助当前程序计数器与历史寄存器完成预测预测结果会对下一个程序计数器数值产生影响。流水线后端会发送训练请求与预测错误处理请求。在本练习中假设分支方向预测器位于右侧图所示假想处理器流水线的取指阶段。本练习仅构建分支方向预测器即图中蓝色虚线矩形所指示部分。分支方向预测采用组合逻辑路径PC寄存器用于计算“取/不取”预测该预测影响下一PC多路选择器从而决定下一周期的PC值。相反模式历史表PHT和分支历史寄存器的更新则在下一个时钟上升沿生效这与触发器存储状态的预期行为一致。Gshare预测器分支方向预测器通常组织为计数器表由程序计数器和分支历史联合索引。表索引是分支地址与历史的哈希值旨在为每个分支和历史组合分配独立的表项或至少减少冲突。每个表项包含一个两位饱和计数器用于记录同一分支和历史模式在过去执行时的分支方向。此类预测器的一个典型示例是Gshare预测器[1]。在Gshare算法中分支地址PC与历史位“共享”表索引位。基本Gshare算法通过将N位分支地址位与N位全局分支历史位进行异或XOR运算计算出N位的PHT表索引。该N位索引随后用于访问具有2^N个表项的两位饱和计数器表。该计数器的值提供预测结果0或1表示不取2或3表示取。训练过程以类似方式对表进行索引。训练PC和历史用于计算表索引然后根据分支的实际结果对该索引处的两位计数器进行递增或递减。参考文献S. McFarling“组合分支预测器”WRL技术说明TN-361993年6月题目描述构建一个Gshare分支预测器采用7位PC和7位全局历史通过异或XOR散列为7位索引。该索引访问一个包含128个表项每个表项为两位饱和计数器的表类似于cs450/counter_2bc。分支预测器应包含一个7位全局分支历史寄存器类似于cs450/history_shift。分支预测器具有两组接口一组用于预测一组用于训练。预测接口在处理器取指阶段使用用于请求针对当前取指指令的分支方向预测。当这些分支沿流水线前进并被执行后分支的真实结果变得已知此时使用实际分支方向结果对分支预测器进行训练。当针对给定PC请求分支预测时predict_valid 1分支预测器产生预测的分支方向以及用于做出该预测的分支历史寄存器状态。随后分支历史寄存器在下一时钟上升沿针对该预测分支进行更新。当请求对某分支进行训练时train_valid 1分支预测器会被告知该分支的PC、分支历史寄存器值、实际分支结果以及是否发生预测错误需要流水线冲刷。更新模式历史表PHT以训练分支预测器使其下次更准确地预测该分支。此外如果被训练的分支发生预测错误还需要将分支历史寄存器恢复至该错误预测分支执行完成后的紧邻状态。如果同一周期内同时存在预测错误训练和对另一更年轻指令的预测请求则两者都希望修改分支历史寄存器。此时训练操作优先因为被预测的分支无论如何都会被丢弃。如果同一周期内对同一PHT表项同时进行训练和预测则预测看到的是训练前的PHT状态因为训练仅在下一个时钟上升沿修改PHT。以下时序图展示了在同一周期内对PHT表项0同时进行训练和预测的时序周期4的训练请求在周期5改变PHT表项状态但周期4的预测请求输出的是周期4的PHT状态而未考虑周期4训练请求的影响。在同一周期内使用PHT表项0同时进行训练和预测时areset 为异步复位信号将整个PHT清零为 2’b01弱不取同时将全局历史寄存器清零为 0。参考答案/* 模块Gshare 分支预测器 功能说明采用PC地址异或全局历史生成查表索引基于2bit饱和计数器实现分支跳转预测 支持正常预测滚动更新全局历史、预测错误历史回滚修正、训练阶段更新模式历史表PHT搭配高电平异步复位完成全局初始化适用于CPU流水线分支预测场景 逻辑优先级固定异步复位 PHT训练更新 误预测历史纠错 正常预测历史移位 保持原值原有业务逻辑完全保留未改动 */moduletop_module(input clk,// 系统工作时钟上升沿触发PHT数组、全局历史寄存器时序更新input areset,// 高电平异步复位边沿触发拉高立即执行初始化无需等待时钟上升沿// 预测查询通路端口组input predict_valid,// 预测有效标志高电平代表本次分支预测查询合法可输出预测结果并后续滚动更新全局历史input[6:0]predict_pc,// 待预测分支指令7位PC地址参与查表索引运算output predict_taken,// 分支预测结果输出1预测分支跳转0预测分支不跳转output[6:0]predict_history,// 实时输出当前7位全局分支历史寄存器快照供给外部模块调用// 训练纠错通路端口组input train_valid,// 训练有效标志高电平代表本次分支真实结果有效允许更新对应PHT表项饱和计数值input train_taken,// 分支真实跳转结果1分支实际跳转0分支实际不跳转用于PHT计数更新、误预测历史修正input train_mispredicted,// 预测错误标记高电平表示上一轮预测出错触发全局历史回滚纠错逻辑input[6:0]train_history,// 出错前保存的7位全局历史快照撤销错误预测写入的无效历史记录input[6:0]train_pc// 本次训练对应的分支7位PC地址参与PHT更新索引运算);// 内部寄存器定义reg[6:0]history;// 7bit全局分支移位寄存器记录最近7次分支跳转走向参与索引计算与滚动更新reg[1:0]pht[0:127];// 128项模式历史表(PHT)每项存储1个2bit饱和计数器记录对应分支长期跳转倾向integer i;// 循环遍历整型变量仅异步复位阶段遍历初始化全部PHT表项// 组合逻辑实时完成查表索引计算与预测结果输出wire[6:0]pred_indexpredict_pc^history;// Gshare核心算法PC异或全局历史融合局部PC特征、全局分支趋势生成查表索引assign predict_taken(pht[pred_index]2b10)?1b1 : 1b0;// 2bit饱和计数判定计数≥10判定跳转否则判定不跳转assign predict_historyhistory;// 直通输出当前全局历史快照组合逻辑实时跟随寄存器值变化// 时序逻辑复位初始化、PHT训练更新、全局历史更新原有判断分支、边界约束完整保留always (posedge clk or posedge areset)beginif(areset)begin// 异步复位执行逻辑全局历史清零所有PHT表项初始化为弱不跳转默认态2b01history7d0;for(i0;i128;ii1)pht[i]2b01;endelsebegin// PHT训练更新分支训练有效时按真实分支结果做饱和增减if(train_valid)begin// 训练索引与预测索引算法一致训练PC异或出错前历史保证查表、更新指向同一表项if(train_taken)begin// 分支实际跳转计数值递增上限饱和锁定2b11避免溢出回绕if(pht[train_pc^train_history]2b11)pht[train_pc^train_history]pht[train_pc^train_history]1b1;endelsebegin// 分支实际不跳转计数值递减下限饱和锁定2b00避免数值下溢if(pht[train_pc^train_history]2b00)pht[train_pc^train_history]pht[train_pc^train_history]-1b1;end end// 全局历史更新分支误预测回滚优先级高于正常预测移位if(train_validtrain_mispredicted)begin// 误预测恢复逻辑截取错误前历史高6位拼接真实分支结果覆盖末位撤销错误预测写入的无效记录history{train_history[5:0],train_taken};endelseif(predict_valid)begin// 正常预测更新逻辑旧历史左移丢弃最早记录末位追加本次预测结果滚动存储history{history[5:0],predict_taken};end// 无触发条件时history默认保持原值无需额外赋值end end endmodule输出结果

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价