smalloc 发表于 2010-09-28 22:06

《硬件软件接口》上有点不清楚

本帖最后由 smalloc 于 2010-09-29 11:05 编辑

单时钟周期的指令设计是所有的动作在一个时钟内完成
而多周期可以配合流水线
那么分阶段的最小单元的限制条件是什么?
在一个时钟内完成的动作内部数据通路只能有且必有一次寄存?

prolj 发表于 2010-09-29 10:46

忘了,我身边全是设计Arch的。

smalloc 发表于 2011-01-02 22:51

本帖最后由 smalloc 于 2011-01-03 12:30 编辑

由这个帖子 http://linux.chinaunix.net/bbs/thread-1176129-1-1.html
回想起了这个帖子.上面的结论是成立的.
在中文版本189面讲的就是这个问题.
另外图5-4中说:状态单元的更新由时钟边缘触发,所以不可能在一个时钟周期内出现反馈.
考虑这个图.
------->[状态单元]--------------->(组合逻辑)----------------
|                                                                                    |
------------------------------------------------------------
但是这段话实际上与523面的描述不是精确符合
523面对D触发器的描述为主从锁存器(一般数字电路书上叫主从触发器),通过时钟上 下2个边缘控制.即在2个边缘都有电路变化.我觉得这个才是真实的不会反馈的原因.
考虑只有一级触发器时,首先边缘触发方式有2种,主要是控制数据有效传入时,分为元件延时和反馈延时,其效果就是在一个很短的水平电平期间允许输入.所以本质上和电平触发区别并不大.但是不管哪种方式.在输出后通过组合电路反映到输入,而输入通过边缘期间控制输出, 是不可能不发生反馈的.
520面也提到了一种时钟控制方法.用时钟决定何时数据有效.这实际上一种比较慢速的方法.可能数据有效无效要多个时钟周期精确控制.当然并不意味着只有一级的时候不会发生反馈.

cjaizss 发表于 2011-01-03 01:20

一般单沿触发器,一个时钟周期只可以变一次;
双沿触发器,一个时钟可以变两次。
话说回来,我没有用过支持双沿的fpga

smalloc 发表于 2011-01-03 12:56

上面说的改变2次.不是指触发器外面,而是指里面.因为存在主从结构.从外面看也只一次
比如假设是上升边沿触发,对与上图,从输出经过组合电路改变主锁存器,在下降边沿,主再改变从.
如果没有主从结构,仅在上升边沿完成所有的操作,很难想象不反馈.除非触发器输出的电信号载体是被"挤"到组合电路中去.并且一旦出去就不再影响.也就是单向的挤,还得有一点延时,当信号再从组合电路出来进入触发器输入.这个时候又要保证输出已经被钳断...
这个方式存在的一种可能电路是

------->----->-------(组合逻辑)----->
这个结构就和主从触发器一样了.区别在于在一个时钟上升边沿要精确通过延时做到:边沿2先有效输入开启,边沿1再开启,在状态单元输出改变前边沿2禁止,也就是保证整个路不出现环.

cjaizss 发表于 2011-01-03 22:44

本帖最后由 cjaizss 于 2011-01-03 22:45 编辑

上面说的改变2次.不是指触发器外面,而是指里面.因为存在主从结构.从外面看也只一次
比如假设是上升边沿触发 ...
smalloc 发表于 2011-01-03 12:56 http://linux.chinaunix.net/bbs/images/common/back.gif


    我说的双沿触发器改变两次当然是指该“寄存器”的值(输出)被改变两次,否则哪能叫双沿触发器?一般不会使用这样的触发器

cjaizss 发表于 2011-01-04 22:44

我说的双沿触发器改变两次当然是指该“寄存器”的值(输出)被改变两次,否则哪能叫双沿触发器? ...
cjaizss 发表于 2011-01-03 22:44 http://linux.chinaunix.net/bbs/images/common/back.gif


    给一个比较简单的双沿触发器的架构,用verilog如下描述,由三个两路复用器搭成
module MUX(out,in0,in1,sel);
input in0,in1,sel;
output out;
assign out=sel?in1:in0;
endmodule

module DET_ff(D,clk,Q);
input D,clk;
output Q;
wire sig0,sig1;
MUX mux1(sig0,sig0,D,clk);
MUX mux2(sig1,D,sig1,clk);
MUX mux3(Q,sig0,sig1,clk);
endmodule

cjaizss 发表于 2011-01-04 22:46

我们再来写一个testbench.
其中D,clk部分我用以下脚本生成
#!/bin/bash
clk=0
D=0
for((i=1;i<100;i++));do
      echo '#10;'
      let x=RANDOM%2
      if [ $x = 1 ];then
                let D=\!D;
                echo D="$D;"
      else
                let clk=\!clk;
                echo clk="$clk;"
      fi
done
之后生成的test bench如下:
module test_bench_DET_ff;
reg D,clk;
wire Q;
initial
begin
clk=0;
D=0;
#10;
D=1;
#10;
D=0;
#10;
clk=1;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
clk=0;
#10;
clk=1;
#10;
clk=0;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
clk=1;
#10;
D=1;
#10;
clk=0;
#10;
D=0;
#10;
D=1;
#10;
clk=1;
#10;
clk=0;
#10;
clk=1;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
clk=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
clk=1;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
clk=0;
#10;
clk=1;
#10;
D=0;
#10;
clk=0;
#10;
clk=1;
#10;
D=1;
#10;
clk=0;
#10;
clk=1;
#10;
clk=0;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
clk=1;
#10;
D=1;
#10;
clk=0;
#10;
D=0;
#10;
D=1;
#10;
clk=1;
#10;
D=0;
#10;
D=1;
#10;
clk=0;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
clk=1;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
clk=0;
#10;
clk=1;
#10;
D=0;
#10;
clk=0;
#10;
clk=1;
#10;
clk=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
clk=1;
#10;
clk=0;
#10;
clk=1;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
clk=0;
#10;
clk=1;
#10;
clk=0;
#10;
clk=1;
#10;
D=0;
#10;
clk=0;
#10;
D=1;
#10;
D=0;
#10;
D=1;
#10;
D=0;
#10;
clk=1;
#10;
clk=0;
#10;
D=1;
#10;
clk=1;
#10;
clk=0;
#10;
clk=1;
#10;
clk=0;
#10;
clk=1;
#10;
clk=0;

$stop();   
end
DET_ff A(D,clk,Q);
endmodule

cjaizss 发表于 2011-01-04 22:50

modlesim仿真结果如下:

cjaizss 发表于 2011-01-05 10:18

modlesim仿真结果如下:
cjaizss 发表于 2011-01-04 22:50 http://linux.chinaunix.net/bbs/images/common/back.gif


    带复位的双沿触发
module MUX(out,in0,in1,sel);
input in0,in1,sel;
output out;
assign out=sel?in1:in0;
endmodule

module DET_ff(D,clk,rst,Q);
input D,clk,rst;
output Q;
wire sig0,sig1;
wire _sig0,_sig1;
parameter INIT_VALUE_AFTER_RESET=0;
assign sig0=rst?INIT_VALUE_AFTER_RESET:_sig0;
assign sig1=rst?INIT_VALUE_AFTER_RESET:_sig1;
MUX mux1(_sig0,sig0,D,clk);
MUX mux2(_sig1,D,sig1,clk);
MUX mux3(Q,sig0,sig1,clk);
endmodule
页: [1] 2 3
查看完整版本: 《硬件软件接口》上有点不清楚