前进律动者———PC计数器

介绍

我们要写的程序在编译器便后成为了一串串cpu指令集存在ram中,我们需要一个计数器产生地址数据给ram寄存器从而取出指令,这个计数器就是PC(program counter)寄存器,简称程序计数器。

引脚介绍

  • clk 时钟信号线,决定了cpu的频率
  • reset 复位信号,高脉冲后计数器归零
  • model_sel 0为步进模式1为擦写模式
  • load_alue 擦写模式时载入的值
  • pc 向ram输出地址

功能介绍

PC计数器有两个模式,步进模式和擦写模式,步进模式下,PC计数器在时钟上升沿时加一,擦写模式下,PC计数器在时钟上升沿时被载入load_value。向ram输出地址值

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module pc_counter(
input reg clk, // 时钟信号线,决定了CPU的频率
input reg reset, // 复位信号,高脉冲后计数器归零
input reg model_sel, // 模式选择,0为步进模式,1为擦写模式
input reg [7:0] load_value, // 擦写模式时载入的值
output reg [7:0] pc // 向RAM输出的地址
);

// 在时钟上升沿和/或复位信号的上升沿发生时,根据模式选择信号更新PC的值
always @(posedge clk or posedge reset) begin
if (reset) begin
pc <= 8'b0; // 复位信号激活时,PC归零
end else if (model_sel) begin
pc <= load_value; // 如果处于擦写模式,PC更新为load_value
end else begin
pc <= pc + 1; // 步进模式,PC按顺序递增
end
end
endmodule

测试代码

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
`timescale 1ns / 1ps

module pc_counter_tb;

// Inputs
reg clk;
reg reset;
reg model_sel;
reg [7:0] load_value;

// Output
wire [7:0] pc;

initial begin
// 初始化
clk = 0;
reset = 0;
model_sel = 0;
load_value = 0;

// 模拟复位
#10 reset = 1; #10 reset = 0;

// 步进模式测试
#20 model_sel = 0;

// 模拟几个时钟周期
#100;

// 擦写模式测试,载入值为55
#10 model_sel = 1; load_value = 8'd55;
#10 model_sel = 0; // 切换回步进模式

// 继续模拟时钟周期
#100;

// 模拟结束
#10 $finish;
end

// 产生时钟信号
always #5 clk = !clk;

endmodule

// 实例化PC计数器模块
pc_counter uut (
.clk(clk),
.reset(reset),
.model_sel(model_sel),
.load_value(load_value),
.pc(pc)
);


结语

PC计数器的频率决定了整个cpu的频率,并且与判决器相连实现的跳转功能。

整点二次元

img1