|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
我们看ARM的架构体系,比较麻烦的是LDM指令。LDM指令是这样的,32位指令的低16bit会对应寄存器组的R0~R15。某一个bit设定为1,那么该bit对应的寄存器会作为目标寄存器,把数据从RAM内读出,写入该寄存器。但是哪一个bit是1还是0,这是随机的。如果我们处理这条LDM指令,自然是从低位到高位,1 bit占据一个周期进行处理,然后该bit复位为0,直到所有的bit全部变为0。
现在问题出来了,cmd[15:0]如何完成这样的操作呢?它的16个bit每一个bit都可能是1,我们如何能够让它从低位到高位,不断的从1变成0,直到所有的1全部变成0?如果把cmd[15:0]当成一个整体考虑,那么我们无论如何是无法完成这个操作的。因为cmd[15:0]每一bit是0是1的情况有2^16种,难道我们要穷举出来?
可能很多人在尝试做ARM处理器实现的时候,都会碰到这个拦路虎,无法对全功能指令进行处理。现在Verilog描述技巧派上了用场。看下面,对cmd的描述代码:
- always @ ( posedge clk or posedge rst )
- if ( rst )
- cmd <= #`DEL 32'd0;
- else if ( cpu_en )
- if ( ~hold_en )
- cmd <= #`DEL code;
- else if ( cmd_is_swp ) begin
- cmd[27:25] <= #`DEL 3'b110;
- cmd[15:12] <= #`DEL cmd[3:0];
- end
- else if ( cmd_is_multl )
- cmd[27:25] <= #`DEL 3'b110;
- else if ( cmd_is_ldm ) begin
- cmd[0] <= #`DEL 1'b0;
- cmd[1] <= #`DEL cmd[0] ? cmd[1] : 1'b0;
- cmd[2] <= #`DEL (|(cmd[1:0])) ? cmd[2] : 1'b0;
- cmd[3] <= #`DEL (|(cmd[2:0])) ? cmd[3] : 1'b0;
- cmd[4] <= #`DEL (|(cmd[3:0])) ? cmd[4] : 1'b0;
- cmd[5] <= #`DEL (|(cmd[4:0])) ? cmd[5] : 1'b0;
- cmd[6] <= #`DEL (|(cmd[5:0])) ? cmd[6] : 1'b0;
- cmd[7] <= #`DEL (|(cmd[6:0])) ? cmd[7] : 1'b0;
- cmd[8] <= #`DEL (|(cmd[7:0])) ? cmd[8] : 1'b0;
- cmd[9] <= #`DEL (|(cmd[8:0])) ? cmd[9] : 1'b0;
- cmd[10] <= #`DEL (|(cmd[9:0])) ? cmd[10] : 1'b0;
- cmd[11] <= #`DEL (|(cmd[10:0])) ? cmd[11] : 1'b0;
- cmd[12] <= #`DEL (|(cmd[11:0])) ? cmd[12] : 1'b0;
- cmd[13] <= #`DEL (|(cmd[12:0])) ? cmd[13] : 1'b0;
- cmd[14] <= #`DEL (|(cmd[13:0])) ? cmd[14] : 1'b0;
- cmd[15] <= #`DEL (|(cmd[14:0])) ? cmd[15] : 1'b0;
- end
- else;
- else;
复制代码 在认定cmd是LDM指令后,也就是cmd_is_ldm生效后,我们就必须从cmd[0]开始不断的把1变成0,直到最后一个1。在上面的实现代码中,我们不是吧cmd[15:0]作为整体考虑,而是对每一个bit作为个体考虑,那么各个击破,就达到了目标。
以cmd[0]来说,不管cmd[0]是0还是1,那么下一个周期它必然等于0。
以cmd[1]来说,它要看cmd[0]是否等于1,如果cmd[0]等于1,那么这一周期轮不上cmd[1]从1变成0,它可以保持不变;如果cmd[1]等于0,那么对不起,cmd[1]也会不管等于啥,都必须等于0。
以cmd[2]来说,它要看的对象是cmd[1:0]中间是否含有一个1,只有cmd[2]前面有一个1存在,那么cmd[2]就可以保持不变,没有它的事,有前面的bit顶着呢;如果cmd[1:0]全部等于0,那么cmd[2]也就必须强制等于0。
以此类推,cmd[15:3]都可以采用这个方法描述。
那么,不管cmd[15:0]是何种bit图案,那么cmd[15:0]都会从低到高的把1电平变成0电平。
LDM指令的cmd[15:0]含有几个1,那么cmd[15:0]也就会有几个周期来变成全0,因此我们就实现了对LDM指令的分化,我们只要对每一个周期的最低bit进行处理,完成单周期的LDR操作即可。 |
|