碎碎思 · 2021年08月13日

你见过1-bit CPU吗?

古老CPU启示录-MC14500 1位CPU(ICU) 

简介

在20世纪80年代4位、8位CPU逐渐成为主流,但是当时的CPU发展还处于探索阶段,所以各种“奇葩”的CPU都有出现,今天给大家带来1-bit CPU MC14500和GI SBA。两者差不多以MC14500为例看下这款“奇葩”CPU。
image.png

MC14500是一种工业控制单元(ICU),也被认为是1位处理器。它由摩托罗拉(Motorola)生产,但几年前已停止生产。如今,MC14500已经被价格合理的FPGA取代了,包括其所有外设和程序存储器。至今仍存在使用MC14500设计的不同原因:

1、为旧的MC14500计算机创建备件;

2、重复使用MC14500软件;

3、FPGA开发(VHDL代码=>电子专家)与应用程序(应用工程师)之间的分离;

4、低成本PLC替代品;

5、在现代FPGA上运行具有历史意义的东西很有趣;

6、使用FPGA的学习项目。
image.png

框图

数据手册:http://www.brouhaha.com/~eric...

特点:

(1)16条指令;

(2)编程容易;

(3)容易掌握,不需要特殊的技术人员;

(4)由于使用外部存储器,系统变得容易;

(5)能满足用户的特定需求,具有丰富的灵活性;

(6)能满足用户的特定需求,具有丰富的灵活性;

(7)能够扩展以适应所有系统的规模和复杂程度;

(8)能够进行程序设计;

(9)B系列C-MOS符合JEDE规格;

(10)噪音容限大;

(11)不工作时漏电流小;

(12)工作电压3~18V;

(13)时钟频率范围广,一般工作频率1MHz(VDD=5V,一个时钟执行一条指令);

(14)信号输入和TTL互换;

(15)将判断作为中心工作,超过微处理器的性能;

(16)应用范围广,由继电器回路开始的逻辑判断处理到中速度的串行数据处理,还能减轻超负荷的微处理器系统的工作。

MC14500允许使用IO地址读取输入位。该位可以使用4位指令和内部1位结果寄存器RR进行处理。结果可以写入IO地址的输出位。

输入和输出数据位可以是物理输入和输出,其中可以连接电线,但它们可以连接到其他设备作为RAM或定时器。

IO的寻址完全在MC14500外部完成。MC14500的所选指令的4位和外部IO多路复用器的IO地址行导致程序存储器的数据宽度。MC14500使用术语“内存字”来表示从程序内存中输出的数据。本文档使用术语“command”作为“memory word”的同义词。因此,命令由两部分组成:指令和IO地址。

由于IO地址在MC14500的外部,因此不同实现之间的命令可能不同。此外,命令中4个指令位的位置也取决于设计。指令位可能占用命令中的高位或低位。

MC14500不包含从程序存储器中寻址要处理的命令的程序计数器。因此,MC14500设计的程序计数器位数可能不同。

程序内存或命令的宽度是指令的4位加上IOaddress行数。小型MC14500设计将使用8位宽的程序存储器,能够选择多达16个IO地址。由于这并不多,许多MC14500设计使用12位宽的程序存储器,可以选择多达256个IO地址。12位宽的程序存储器使用过去存在的4位宽的ROM设备。其他MC14500设计使用8位宽的程序存储器,但是每个MC14500命令有两个字节被读取,因此形成了一个16位宽的命令,能够寻址多达4096个IO地址线,用于物理IO、单位宽RAM和定时器硬件。在MC14500设计中,从程序存储器中读取两次会产生另一种变化,从程序中读取的第一个字节可能在一种设计中是低字节,但在另一种设计中是命令的高字节。指令集如下:

image.png

利用MC14500搭建的外围系统:

image.png

MC14500模拟器

MC14500模拟器使用web技术和javascript来独立于平台,并且在将来也可以使用。这种实现的一个缺点是javascript模拟器不能访问用户的文件系统或硬件。

模拟器在支持svg的浏览器上运行。模拟器使用的硬件架构如下图所示。
image.png

地址:https://www.linurs.org/mc1450...

按下“步进”按钮意味着下降的时钟边缘,因此MC14500加载指令和输入数据。

释放“步进”按钮意味着上升的时钟边缘,因此MC14500写入数据。程序计数器增加。在程序存储器访问时间之后,下一条指令和IO地址出现在MC14500和输出、输入或RAM上。

详细的介绍就不过多赘述,网上还有利用Python进行汇编程序和反汇编程序的介绍。

FPGA实现

image.png

利用MC14500搭建的CPU

从上面的介绍可以看出MC14500和FPGA有很多相似的地方,接下来就用FPGA实现一下这款单比特CPU。

module mc14500b(
    input clk,
    input rst,
    input [3:0] i_inst,
    input i_data,
    output reg write = 0,
    output reg jmp = 0 ,
    output reg rtn = 0,
    output reg flag0 = 0,
    output reg flagf = 0,
    output reg o_rr = 0,
    output reg o_data = 0
    );
    reg ien = 0, oen = 0;
    reg skip = 0;
    always @(negedge clk or posedge rst) begin
        // Reset any flags from last clock.
        jmp <= 0;
        rtn <= 0;
        flag0 <= 0;
        flagf <= 0;
        write <= 0; // FIX this it's not right technically.
        if (rst) begin
            // reset behavior. reset internal flags and ignore clock.
            ien <= 0;
            oen <= 0;
            o_rr <= 0;
            skip <= 0;
        end else begin
        if (~skip) begin // skip
        case(i_inst)
        4'b0000 : flag0 <= 1; // NOPO
        4'b0001 : o_rr <= ien & i_data; // LD
        4'b0010 : o_rr <= ien & ~i_data; // LDC
        4'b0011 : o_rr <= ien & (i_data & o_rr); // AND
        4'b0100 : o_rr <= ien & (~i_data & o_rr); // NAND
        4'b0101 : o_rr <= ien & (i_data | o_rr); // OR
        4'b0110 : o_rr <= ien & (~i_data | o_rr); // NOR
        4'b0111 : o_rr <= ien & (o_rr == i_data); // XNOR
        4'b1000 : begin // STO
        // DATA -> RR, WRITE -> 1 for a clock (if oen is allowed).
            o_data <= oen & o_rr;
            write <= oen;
        end
        4'b1001 : begin // STOC
        // DATA -> ~RR, WRITE -> 1 for a clock.
            o_data <= ~o_rr;
            write <= oen;
        end
        4'b1010 : ien <= i_data;
        4'b1011 : oen <= i_data;
        4'b1100 : jmp <= 1;
        4'b1101 : begin // RTN
            rtn <= 1;
            skip <= 1;
        end
        4'b1110 : skip <= ~o_rr;
        4'b1111 : flagf <= 1;
       
        endcase
        end
        else begin // reset skip flag after clocking with skip once.
            skip <= 0;
        end
        end
    end // neg edge
//    always @(posedge clk) begin
//        write <= 0;
//    end
endmodule

“CPU是复杂的状态机”,仿真之类的详见:

https://github.com/suisuisi/o...

整体比较简单就不解释了。

原出处:FPGA 的逻辑
作者:碎碎思

相关文章推荐

更多FPGA技术干货请关注FPGA 的逻辑技术专栏。
推荐阅读
关注数
10614
内容数
577
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息