SOC微体系结构设计

8时钟分频电路

  1. 偶数分频器(占空比为50%)

方案一:当计数器计到N/2 - 1时,将输出电平进行一次翻转,同时给计数器一个输出复位信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 6分频为例
architecture a of div is
signal clk:std_logic:='0';
signal count:std_logic_vector(2 downto 0):='000';
begin
process(clk_in) --原来的时钟频率
begin
if(clk_in'enent and clk_in='1') then
if count /=2 then --N=6,所以是2,这里是≠2
count=count+1;
else
clk<= not clk
count<='000';
end if;
end if;
end process;
clk_out<=clk;
end a;

方案二:当计数器输出为[0 , N/2-1]时,时钟输出为一个值,而为[N/2 , N-1]时,又输出为一个值,计数器为N-1的时候,复位计数器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
architecture b of div is
signal count:std_logic_vector(2 downto 0):='000';
begin
process(clk_in)
begin
if(clk'event and clk_in='1')then
if count<5 then
count=count+1;
else count = '000';
end if;
end if;
end process;
process(count)
begin
if(count < 3) then
clk_out<='0';
else clk_out<='1';
end if;
end process;
end b;

-- 占空比为0.5的7分频 3/7
port(
clk1,clk2;
cnt1,cnt2;
);
process(clk_in)
begin
if(rising_edge(clk1)) then
if(cnt<6) then cnt<=cnt+1;
else
if(cnt<3) then clk='1';
else clk='0';

串行进位加法器

image-20240509234603168

image-20240509235401467 image-20240509235413859

并行进位加法器

image-20240510000028581

image-20240510000052812

有限状态机

  • Moore状态机设计输出信号只和当前状态有关,下一个状态和当前状态以及输入信号有关
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
library IEEE
use ieee.std_logic_1164.all
entity more is
port(clk,rst:in std_logic;
state_input:in std_logic;
state_output:out std_logic_vector(1 downto 0);
)
end more;
architecture Behaviorial of more is
type states is (st0,st1,st2,st3); -- 定义状态枚举类型
signal state:states;
begin
-- 下一个状态的切换
process(clk,rst)
begin
if(rst='1')then
state<=st0;
elsif(clk'event and clk='1')then
case state is
when st0=>
if state_input='0' then state<=st0;else state<=st1;
end if;
when st1=>
if state_input='0' then state<=st1;else state<=st2;
end if;
when st2=>
if state_input='0' then state<=st2;else state<=st3;
end if;
when st3=>
if state_input='0' then state<=st3;else state<=st0;
end if;
end case;
end if;
end process;
-- 输出信号
process(state)
begin
case state is
when st0=>
state_output<='00';
when st1=>
state_output<='01';
when st2=>
state_output<='10';
when st3=>
state_output<='11';
end case;
end process;
end Behavioral;
  • Mealy状态机:输出信号与当前状态和输入都相关
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
library IEEE
use ieee.std_logic_1164.all
entity more is
port(clk,rst:in std_logic;
state_input:in std_logic;
state_output:out std_logic_vector(1 downto 0);
)
end more;
architecture Behaviorial of more is
type states is(st0,st1,st2,st3); -- 定义状态枚举类型
signal state:states;
begin
-- 下一个状态的切换
process(clk,rst)
begin
if(rst='1')then
state<=st0;
elsif(clk'enent and clk='1')then
case state is
when st0=>
if state_input='0' then state<=st0;else state<=st1;
end if;
when st1=>
if state_input='0' then state<=st1;else state<=st2;
end if;
when st2=>
if state_input='0' then state<=st2;else state<=st3;
end if;
when st3=>
if state_input='0' then state<=st3;else state<=st0;
end if;
end case;
end if;
end process;
-- 输出信号
process(state)
begin
case state is
when st0=>
if state_input='0' state_output<='00';else state_output<='01';end if;
when st0=>
if state_input='0' state_output<='00';else state_output<='01';end if;
when st1=>
if state_input='0' state_output<='01';else state_output<='10';end if;
when st2=>
if state_input='0' state_output<='10';else state_output<='11';end if;
when st3=>
if state_input='0' state_output<='11';else state_output<='00';end if;
end case;
end process;
end Behavioral;

  • 按键消抖电路
image-20240515192350209 image-20240515215448857 image-20240515215524990

组合逻辑电路设计

  1. 编码器/译码器设计
image-20240511221120807
  • 3-8译码器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
library ieee;
use ieee.std_logic_1164.all;


entity Decoder3to8 is
port (
input : in std_logic_vector(2 downto 0);
output : out std_logic_vector(7 downto 0);
enable: in std_logic
);
end entity Decoder3to8;

architecture Behavioral of Decoder3to8 is
begin
process (input, enable)
begin
if enable = '0' then
case input is
when "000" =>
output <= "00000001";
when "001" =>
output <= "00000010";
when "010" =>
output <= "00000100";
when "011" =>
output <= "00001000";
when "100" =>
output <= "00010000";
when "101" =>
output <= "00100000";
when "110" =>
output <= "01000000";
when "111" =>
output <= "10000000";
when others =>
output <= "00000000";
end case;
else
output <= "00000000";
end if;
end process;
end architecture Behavioral;
  1. 多路选择器设计(4选一数据选择器)
image-20240511221335518
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 端口定义
PORT(A0:IN STD_LOGIC
A1: IN STD_LOGIC
Data:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
EN: IN STD_LOGIC
Y: OUT STD_LOGIC );
-- 结构体部分: 用WHEN...ELSE语句
Y <= Data(0) WHEN A=“00ELSE
Data(1) WHEN A=“01ELSE
Data(2) WHEN A=“10ELSE
Data(3) WHEN A=“11ELSE
0’;
-- 或者也可以用CASE WHEN
CASE A IS
WHEN00” => Y <= Data(0);
WHEN01” => Y <= Data(1);
WHEN10” => Y <= Data(2);
WHEN11” => Y <= Data(3);
WHEN OTHER Y <= ‘0’;
  1. 数码转换电路设计

将四位二进制转十进制的BCD码,同时将BCD码再转换成七段显示器码

image-20240511222533706

存储器

  1. RAM(随机存取存储器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
-- SRAM实现
-- 端口定义
port(address: in std_logic_vector(3 downto 0);
data: inout std_logic_vector(7 downto 0);
cs,oe,we:in std_logic
);
Architecture behav of ram16*8 is
subtype word is std_logic_vector(7 downto 0);
type ram_array is array(0 to 15) of word;
signal index: in integer range 0 to 15;
signal sram_store:ram_array;
begin
index <= CONV_INTEGER(address)
process(address,cs,oe,we,data)
begin
if cs='0' then
if we='1' then -- 写入数据
sram_store(index)<=data;
elsif oe = '1' then --读出数据
data<=sram_store(index);
else
data<='zzzzzzzz'; --设置总线为三态
end if;
else
data<='zzzzzzzz';
end if;
end process;
end behav;
  1. ROM(只读存储器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-- 设计一个256*8bit的ROM 8位地址线,8位数据线,使能oe
-- 文件类型引用
use ieee.std_logic_textio.all
use std.textio.all

entity MyRom is
generic(wordlength:integer:=8;
addlength:integer:=8);
port(
addr:in std_logic_vector(addrlength-1 downto 0);
oe:in std_logic;
dout: out std_logic_vector(wordlength-1 downto 0)
);
end entity MyRom;

architecture behavior of MyRom is
type matrix is array(integer range<>) of std_logic_vector(wordlength-1 downto 0);
signal rom:matrix(0 to 2**addlength-1);

procedure load_rom(signal data_word:out matrix) is
file romfile:text open read_mode is "romfile.dat";
variable lbuf:line;
variable i:integer:=0;-- 循环变量
variable fdata:std_logic_vector(7 downto 0);
begin
-- 读数据直至文件末尾
while not endfile(romfile) loop
readline(romfile,lbuf); -- 逐行读数据
read(lbuf,fdata); -- 将行数据转成8位向量,保存到变量fdata中
data_word(i)<=fdata;
i:=i+1;
end loop;
end procedure;

begin
load_rom(rom);
dout<=rom(conv_integer(addr)) when oe='0' else
(others=>'z');
end behavior;
  1. FIFO先进先出:利用双端口RAM和读写地址产生模块

同步控制的FIFO读写时钟相同,异步控制的FIFO读写时钟不同;

  • 与存储器的区别:没有外部读写地址线,数据地址由内部读写指针自动+-完成

判断FIFO空和满:

当wr_ptr=rd_ptr时,FIFO数据为空;

当wr_ptr - rd_ptr = M-1 或者 rd_ptr - wr_ptr = 1时,FIFO数据为满;

当wr_ptr >= rd_ptr时,wr_ptr - rd_ptr为FIFO内部的数据个数;

当wr_ptr <= rd_ptr时 ,M-(rd_ptr - wr_ptr) 为FIFO内数据个数;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
1. 双端口RAM
entity dualram is
generic(
width: positive:=8; -- positive代表≥0的整数
depth: positive:=8
);
port(
-- port a 只用来写
clka:in std_logic;
wr:in std_logic;
addra:in std_logic_vector(depth-1 downto 0);
datain:in std_logic_vector(width-1 downto 0);
-- port b只用来读
clkb:in std_logic;
rd:in std_logic;
addrb:in std_logic_vector(depth-1 downto 0);
dataout:out std_logic_vector(width-1 downto 0)
);
end entity dualram;

architecture Behavioral of dualram is
type ram is array(2**depth-1 downto 0) of std_logic_vector(width-1 downto 0);
signal dualram:ram;
begin
process(clka)
begin
if clka'enent and clka='1' then
if wr='0' then
dualram(conv_integer(addra))<=datain;
end if;
end if;
end process;
process(clkb)
begin
if clkb'enent and clkb='1' then
if rd='0' then
dataout<=dualram(conv_integer(addra));
end if;
end if;
end process;

2. 写地址计数器
if rst='0' then
wr_pt_t<=(others=>'0');
elsif clk'event and clk='1' then
if wq='0' then
wr_pt_t<=wr_pt_t+1;
end if;
end if;

wr_pt<=wr_pt_r

3. 读地址计数器
if rst = '0' then
rd_pt_t<=(others=>0);
elsif clk'event and clk='1' then
if rq='0' and empty='0' then -- FIFO不为空
rd_pt_t<=rd_pt_t+1;
end if;
end if;
rd_pt<=rd_pt_t;
4. 空满状态产生器
if rst='0' then
empty<='1';
elsif clk'enent and clk='1' then
if wr_pt=rd_pt then
empty<='1';
else empty<='0';
----
if rst='0' then full<='0';
elsif clk'event and clk='1' then
if wr_pt>rd_pt then
if(rd_pt+depth)=wr_pt then full<='1';
else full<='0';
else
if (wr_pt+1)=rd_pt then full<='1';
else full<='0';
1
2
3
4
5
6
-- 存储单元数据结构
整数数组:
type memory is array(integer range<>) of integer;
位矢量:
subtype word is std_logic_vector(k-1 downto 0);
type memory is array(0 to 2**w-1) of word;

CPU设计

时钟,IR,RN,PC,SP,IO,ALU,微控制器

1.时钟节拍设计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
entity clock is
Port(
clk,rst:in std_logic;
clk1,nclk1:out std_logic; --clk
clk2,nclk2:out std_logic; --clk二分频
w0,w1,w2,w3:out std_logic --节拍信号
);
end clock;
architecture Behavioral of clock is
begin
process(clk)
variable count_clk2:integer:=0;
variable count_w:integer:=0;
begin
if(rst='0')then
w0<='0';
w1<='0';
w2<='0';
w3<='0';
clk1<='0';
nclk1<='1';
clk2<='0';
nclk2<='1';
count_clk2:=0;
count_w:=0;
elsif(rst='1')then
clk1<=clk;
nclk1<=not clk;
if(clk'event and clk='1')then
if(count_clk2=0)then count_clk2:=1;clk2<='1';nclk2<='0';
elsif(count_clk2=1)then count_clk2:=0;clk2<='0';nclk2<='1';
end if;
if(count_w>=0 and count_w<=3)then w0<='1';else w0<='0';end if;
if(count_w>=4 and count_w<=7)then w1<='1';else w1<='0';end if;
if(count_w>=8 and count_w<=11)then w2<='1';else w2<='0';end if;
if(count_w>=12 and count_w<=15)then w3<='1';else w3<='0';end if;
if(count_w<15)then count_w:=count_w+1;else count_w:=0;end if;
end if;
end if;
end process;
end Behavioral;
2. PC程序计数器
image-20240515163615564 image-20240515163649690
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
-- PC 功能分析
1. 加1功能
2. 更新地址功能
3. PC数值送到数据总线
entity myPC is
port(
clk_pc: in std_logic; --PC时钟信号
n_rst: in std_logic; --清零信号
n_ld: in std_logic; --新PC送入,装载新地址
m_pc: in std_logic; --PC值+1控制信号
nPCH, nPCL: in std_logic; --高低位,PC输出总线控制信号
PC: in std_logic_vector(11 downto 0); --PC指针
addr: out std_logic_vector(11 downto 0); --ROM读地址输出
data: inout std_logic_vector(7 downto 0) --PC数值输出到数据总线
);
end myPC;

architecture Behavioral of PC is
signal myPC: std_logic_vector(11 downto 0):="000000000000";
begin
addr <= myPC;
process(n_rst, clk_pc, m_pc, n_ld)
begin
if n_rst='0' then
myPC <= "000000000000"; --清零
data <= "ZZZZZZZZ"; --数据总线高阻态
elsif clk_pc'event and clk_pc='1'then
if m_pc='1' then --PC值+1
myPC <= myPC+1;
elsif n_ld='0' then --送入新PC
myPC<=PC;
end if;
end if;
end process;

process(nPCH, nPCL)
begin
if nPCH='0' and nPCL='1' then
data(3 downto 0) <= myPC(11 downto 8); --高四位输入到数据总线
data(7 downto 4) <= "0000";
elsif nPCL='0' and nPCH='1' then --低位低电平,高位高电平有效
data(7 downto 0) <= myPC(7 downto 0); --低八位输入到数据总线
else
data <= "ZZZZZZZZ"; --数据总线高阻态
end if;
end process;
end Behavioral;
3. 程序存储器ROM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use IEEE.STD_LOGIC_TEXTIO.ALL;  -- 文件操作的库
use STD.TEXTIO.ALL;

entity MyRom is
generic(
wordlength:integer:=8; -- 位宽度
addrlength:integer:=8 -- 地址位
);
Port (
addr:in std_logic_vector(addrlength-1 downto 0); -- ROM地址信号
oe:in std_logic; -- ROM使能
dout:inout std_logic_vector(wordlength-1 downto 0) -- 数据总线
);
end MyRom;

architecture Behavioral of MyRom is
type matrix is array(integer range<>) of std_logic_vector(7 downto 0);
signal rom:matrix(2**addrlength-1 downto 0);
procedure load_rom(signal data_word:out matrix) is --过程调用的参数
file romfile:text open read_mode is "C:\Users\akyna\Codes\vivado\rom\romfile.dat";
--file romfile:text;
--file_open(romfile,file_in,"romfile.txt",read_mode);
variable lbuf:line;
variable i:integer:=0;
variable fdata:std_logic_vector(7 downto 0);
begin
while not endfile(romfile) loop
readline(romfile,lbuf);
read(lbuf,fdata); -- 将每一行数据存入fdata
data_word(i)<=fdata;
i:=i+1;
exit when i=256;
end loop;
end procedure;

begin
load_rom(rom);
dout<=rom(conv_integer(addr))when oe='0'
else "ZZZZZZZZ";
end Behavioral;
4. 指令存储器IR设计
image-20240515163738984 image-20240515163807309
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
-- IR功能分析
1. 传送指令编码到微控制器
2. 生成PC新地址
3. 生成RAM读写地址
entity IR is
port(clk_IR:in std_logic; -- IR时钟信号
nrst:in std_logic; -- 复位信号
LD_IR1,LD_IR2,LD_IR3: in std_logic; -- IR指令存储控制信号
nAren:in std_logic; -- IR中RAM地址控制信号
data:inout std_logic_vector(7downto 0)-- 数据总线
IR:out std_logic_vector(7 downto 2); -- IR指令编码
PC:out std_logic_vector(11 downto 0); -- PC新地址
AR:out std_logic_vector(6 downto 0); -- RAM读写地址
RS:out std_logic; -- 源寄存器
RD:out std_logic; -- 目的寄存器
);
end IR;
architecture behavior od IR is
begin
process(clk_IR,rst)
begin
if nrst='0' then
IR<=(others=>'0');
PC<=(others=>'0');
AR<=(others=>'0');
RS<='0';
RD<='0';
elsif clk'event and clk='1' then
if(LD_IR1='1') then
IR<=data(7 downto 2);
RS<=data(0);
RD<=data(1);
end if;
-- 生成PC地址
if(LD_IR2='1') then
PC(11 downto 8)<=data(3 downto 0);
end if;
if(LD_IR3='1') then
PC(7 downto 0)<=data(7 downto 0);
end if;
if(LD_IR3='1' and nAren='0') then
AR<=data(6 downto 0);
end if;
end if;
end process;
end behavoir;
5. 寄存器RN设计
image-20240515185303407
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-- RN功能分析
1.数据锁存
2.数据读写
entity RN is
Port (
clk_RN: in std_logic; -- RN时钟信号
nreset: in std_logic; -- 复位信号
Ri_EN: in std_logic; -- RN寄存器使能
RDRi: in std_logic; -- RN读信号
WRRi: in std_logic; -- RN写信号
RS: in std_logic; -- 源寄存器
RD: in std_logic; -- 目的寄存器
data : inout std_logic_vector(7 downto 0) -- 数据总线
);
architecture behavioral of RN is
type Rdata is array(7 downto 0) of std_logic_vector(7 downto 0);
signal RDD:Rdata;
begin
process(clk_RN)
begin
if(rising_edge(clk_RN) and RN_EN='0') then
if RDRi='1' then data<=RDD(conv_integer(RS));
elsif WRRi='1' then RDD(conv_integer(RD))<=data;
end if;
end if;
end process;
end Behavioral;
6. 数据存储器RAM设计
image-20240515190642425
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- RAM功能分析
1. 数据存储功能
2. 数据读写功能
entity RAM_m is
Port (
clk_RAM: in std_logic;
n_reset: in std_logic;
RAM_CS: in std_logic;
nRAM_EN: in std_logic; -- RAM输出使能信号
wr_nRD: in std_logic; -- 读写控制,高电平写有效,低电平读有效
AR: in std_logic_vector(6 downto 0); -- RAM地址信号
data:inout std_logic_vector(7 downto 0); -- 数据总线
);
end RAM_m;
architecture Behavioral of RAM_m is
type max is array(integer range<>) of std_logic_vector(7 downto 0); --定义数据类型
signal tmp: max(0 to 2**7-1); --定义ram空间
begin
process(clk_RAM)
begin
if(clk_RAM'event and clk_RAM = '1')then
if(n_reset = '0')then
data <= "00000000";
else
-- 读数据
if(RAM_CS = '1'and wr_nRD = '0' and nRAM_EN = '0')then
data <= tmp(conv_integer(AR));
-- 写数据
elsif(RAM_CS = '1' and wr_nRD = '1')then
tmp(conv_integer(AR)) <= data;
end if;
end if;
end if;
end process;
end Behavioral;
7. 堆栈指针SP设计
image-20240515191510723
1
2
3
4
-- SP功能分析
1. 数据存储功能
2. 加1功能:出栈
3. 减1功能:压栈
image-20240515191844529 image-20240515191910603
8. IO端口设计
image-20240515191958392 image-20240515192155118 image-20240515192227119 image-20240515205158203 image-20240515205219468 image-20240515205459057 image-20240515205514062
Author

Jiawei Hu

Posted on

2024-05-26

Updated on

2024-05-26

Licensed under


Comments