从与或非门开始构建一个计算机的教程(写给软件工程师)四

时序电路(存储)

时序电路

所谓时序电路就是含有时钟信号的电路,时钟信号上下翻转

D 触发器

因为 D 触发器只有一个输入和一个输出,可以用硬件测试。因为 D 触发器是时钟触发的,所以约束文件一定要带上时钟。

IO_LOC "out" 10; // red
IO_LOC "in" 15;
IO_LOC "clk" 45;

D 触发器具有存储功能,其实是通过反馈实现的,所以我们用它来实现存储电路。

Bit

bit 是一位存储,由 D 触发器实现。和单纯的 D 触发器不同,额外使用了数据选择器实现数据的改变。

    wire muxo;
    Mux MUX(.a(out),.b(in),.sel(load),.out(muxo));
        DFFusr DFF1(.clk(clk),.in(muxo),.out(out));

当 load = 1 时,D 触发器的输入被改变,所以 D 触发器的下一个状态改变。

因为时序电路用到了 clk ,所以仿真时 clk 不会自动变化,需要添加 always #1 clk = ~clk; 来使 clk 每隔一个时钟周期翻转一次。

寄存器

因为我们要构建的计算机是 16 位的,所以寄存器是 16 位的,寄存器由 16 个 Bit 组成。

    Bit BIT1(.in(in[0]),.load(load),.out(out[0]), .clk(clk));
    Bit BIT2(.in(in[1]),.load(load),.out(out[1]), .clk(clk));
    Bit BIT3(.in(in[2]),.load(load),.out(out[2]), .clk(clk));
    Bit BIT4(.in(in[3]),.load(load),.out(out[3]), .clk(clk));
    Bit BIT5(.in(in[4]),.load(load),.out(out[4]), .clk(clk));
    Bit BIT6(.in(in[5]),.load(load),.out(out[5]), .clk(clk));
    Bit BIT7(.in(in[6]),.load(load),.out(out[6]), .clk(clk));
    Bit BIT8(.in(in[7]),.load(load),.out(out[7]), .clk(clk));
    Bit BIT9(.in(in[8]),.load(load),.out(out[8]), .clk(clk));
    Bit BIT10(.in(in[9]),.load(load),.out(out[9]), .clk(clk));
    Bit BIT11(.in(in[10]),.load(load),.out(out[10]), .clk(clk));
    Bit BIT12(.in(in[11]),.load(load),.out(out[11]), .clk(clk));
    Bit BIT13(.in(in[12]),.load(load),.out(out[12]), .clk(clk));
    Bit BIT14(.in(in[13]),.load(load),.out(out[13]), .clk(clk));
    Bit BIT15(.in(in[14]),.load(load),.out(out[14]), .clk(clk));
    Bit BIT16(.in(in[15]),.load(load),.out(out[15]), .clk(clk));

PC

PC 又称程序计数器,主要由寄存器实现。PC 有三个条件,分别为 reset load inc 。由三个二选一数据选择器实现,先后次序决定优先级,加 1 由加法器实现。

有三个功能:

  • 当 inc = 1 时,加 1
  • 当 load = 1 时,把 in 的值赋给 PC
  • 当 reset = 1 时,复位

RAM

现代体系结构中 RAM + io 映射等于所谓的主存,本节我们先实现 RAM 。根据 nand2tetris ,RAM 用寄存器实现,让 verilog 自己生成。当然更正确的做法是使用 Fpga 的 block RAM ,但是开源工具不支持: https://github.com/YosysHQ/yosys/wiki/FPGA-family-feature-matrix 。

module RAM(
    input wire clk,
    input wire [15:0] address,
    input wire [15:0] in,
    input wire load,
    output wire [15:0] out
);
    
  reg [15:0] regRAM [0:10]; 
    always @(negedge clk)
    if (load) regRAM[address[3:0]] <= in;

  assign out = regRAM[address[3:0]];
endmodule

低 4 位都用来访问 RAM ,regRAM 代表 10 个 16 位空间。

关于 BlockRAM:http://xilinx.eetrend.com/blog/2020/100049862.html

关于 LUT:https://cloud.tencent.com/developer/article/1794053

代码:https://github.com/buhe/bugu-computer/tree/master/03

你可能感兴趣的:(从与或非门开始构建一个计算机的教程(写给软件工程师)四)