通用寄存器中有三个寄存器,用于寄存一个地址和两个操作数。在执行指令阶段中,通过多个控制信号选择对应的寄存器中数据进行输出或者写入,输出的方向有函数发生器(ALU)和数据选择器。这里R1寄存器和R2寄存器用于储存操作数,C寄存器用于储存地址。
那么通用寄存器需不需要时钟控制呢?对于写入操作显然是需要的,虽然WE是作为写入信号的使能,但是当WE有效时,在同一个执行周期内我们显然只需要写入一次(有必要的话),总线的数据是有可能不断变化的,所以这里不设置时钟的话,要精准地控制其写入个人觉得比较困难。但是读出数据就不一样了,因为通用寄存器里面的内容除了写入会使其值改变之外,其值是不会发生变化的,所以输出既可以由时钟控制也可以不用时钟控制,本人没有用时钟控制,感觉用时钟控制的话可能要多等待一个时钟上升沿。
(1)VHDL代码:
library ieee;
use ieee.std_logic_1164.all;
entity TYJCQ is
port(CLK,RAA1,RAA0:in std_logic;
RWBA1,RWBA0:in std_logic;
WE:in std_logic;
Fin:in std_logic_vector(7 downto 0);
FA:out std_logic_vector(7 downto 0);
FB:out std_logic_vector(7 downto 0));
end TYJCQ;
architecture ST of TYJCQ is
signal R1:std_logic_vector(7 downto 0):="10011000";-- 48<-152->76
signal R2:std_logic_vector(7 downto 0):="00000111";-- 7
signal C:std_logic_vector(7 downto 0):="00001111";-- 15
begin
process(CLK,RAA1,RAA0,RWBA1,RWBA0,Fin,WE)
begin
if(RWBA1='0'and RWBA0='0')then
FB<=R1;
elsif(RWBA1='1')then
FB<=C;
elsif(RWBA1='0'and RWBA0='1')then
FB<=R2;
end if;
if(RAA1='0'and RAA0='1')then
FA<=R2;
elsif(RAA1='1')then
FA<=C;
elsif(RAA1='0'and RAA0='0')then
FA<=R1;
end if;
if((CLK'event and CLK='1')and WE='0')then
if(RWBA1='0'and RWBA0='0')then
R1<=Fin;
elsif(RWBA1='1'and RWBA0='0')then
C<=Fin;
elsif(RWBA1='0'and RWBA0='1')then
R2<=Fin;
end if;
end if;
end process;
end ST;
CLK:时钟信号,当时钟上升沿到来时配合RWBA1与RWBA0对指定的寄存器进行写入;
RAA0,RAA1:控制A输出端口的输出数据来自哪一个寄存器;
RWBA1,RWBA0:控制B端口的输出数据来自哪一个寄存器,以及控制给指定的警察写入数据;
WE:写入使能,高电平有效,有效时允许BUS总线上的数据写入指定的寄存器;
Fin:BUS总线上的数据输入;
FA:A端口的数据输出;
FB:B端口的数据输出。
由仿真结果可知当时钟上升沿到来时,通用寄存器中由RWBA1和RWBA0控制的寄存器会写入Fin的数据,使得下一次该寄存器的数据被输出时,输出的是写入的数据,符合设计的要求,结果正确(有点RAM的味道)。