使用 Verilog 的简单 Moris Mano 计算机设计

Simple Moris Mano Computer Design Using Verilog

我应该设计一个简单的 16 位 Moris Mano 计算机,其组件是 Alu、Control Unit、Registers 和 Bus。

问题是: 我对变量的类型有点困惑。 例如,我应该为 D0,D1 ... D7 和 T0,T1, .. , T7 使用电线,还是应该使用 reg.? 如果我应该使用电线,如何在 Always @(posedge clock) 块中为它们赋值?

我的部分代码如下:

module Control_Unit_Core(PC_inc,DR_inc,AC_inc,AC_clr,IR_load,DR_load,AR_load,PC_load,AC_load,RAM_load,RAM_read,ALU_select,ALU_enable, IR,DR,AC,clock);

output PC_inc,DR_inc,AC_inc,AC_clr,IR_load,DR_load,AR_load,PC_load,AC_load,RAM_load,RAM_read,ALU_enable;    
output [1:0] ALU_select;
input [9:0] IR,DR,AC;
input clock;

reg [2:0] palseCounter=3'b111;
wire [7:0] T=8'b00000000;
wire [7:0] D=8'b00000000;
wire [5:0] B=6'b000000;
wire [9:0] ADDRESS=10'b0000000000;

reg HLT=0,SC_reset=0,I=0,Z=0,R=0;
wire Ram_load=0,DR_load=0,AR_load=0,AC_load=0,IR_load=0,PC_load=0;
wire PC_inc=0,DR_inc=0,AC_inc=0;
wire AC_clr=0;
reg Ram_read=0;
reg Alu_enable=0;
reg [2:0] Bus_select=3'b000;
reg [1:0] Alu_select=3'b00;

always @(posedge clock)
    begin
        pulseCounter <= pulseCounter+1'
        T_Generator(T,HLT,SC_reset,pulseCounter);
        D_B_Generator(D,B,ADDRESS,I,IR);
        Registers_Load_Generator(Ram_load,DR_load,AR_load,AC_load,IR_load,PC_load,D,T,I);
        Z<=AC[9];
        R<=(~I)&D[7]&T[3];
        HLT<=R&B[0];
        Registers_Inc_Clr_Generator(PC_inc,DR_inc,AC_inc,AC_clr,D,T,B,AC,DR,R,Z);
        Bus_Select_Generator(Bus_select,Ram_read,T,D,I);
        Alu_Signal_Generator(Alu_select,Alu_enable,T,D);  

        SC_reset <=(D[0]&T[6])|(D[1]&T[6])|(D[2]&T[6])|(D[3]&T[5])|(D[4]&T[5])|((~I)&D[7]&T[4])|T[7];

    end 
endmodule

此外,T_Generator和D_Generator任务的编写代码如下。

task T_Generator(output [7:0]T,input hlt, SC_reset,inout [2:0]palseCounter);
if(~hlt)
    begin
        if(SC_reset)
            palseCounter=3'b000;    

        case(palseCounter)
            3'b000 : T=8'b00000001;
            3'b001 : T=8'b00000010;
            3'b010 : T=8'b00000100;
            3'b011 : T=8'b00001000;
            3'b100 : T=8'b00010000;
            3'b101 : T=8'b00100000;
            3'b110 : T=8'b01000000;
            3'b111 : T=8'b10000000;
        endcase             

    end
else
    begin
        T=8'b00000000;
        palseCounter=3'b111;
    end
endtask


///------------------------------------
task D_B_Generator(output [7:0] D,output [5:0] B,output [9:0] ADDRESS ,output I,input [9:0] IR);
I=IR[9];
case(IR[8:6])
    3'b000 : D=8'b00000001;
    3'b001 : D=8'b00000010;
    3'b010 : D=8'b00000100;
    3'b011 : D=8'b00001000;
    3'b100 : D=8'b00010000;
    3'b101 : D=8'b00100000;
    3'b110 : D=8'b01000000;
    3'b111 : D=8'b10000000;
endcase
B=IR[5:0];
ADDRESS=IR[5:0];
endtask

提前致谢。

简答:

他们应该注册。并且请重置你的变量,如果你打算综合这个,不要使用声明时间初始化。

中等答案:

如果您在始终块中分配,请使用 reg,否则使用 wire。请永远不要在电线上使用声明时间初始化。在电线的有效使用中,您将遇到驱动器冲突,这会以有趣的方式使您感到困惑。

更长的答案:

在任何时候都可以在不查看先前值的情况下知道它们的值吗?连线用于分配语句和连接之类的事情,因为(从模拟器的角度来看)连线中没有内存的概念。只需查看分配的 RHS,就知道 LHS 会 be.Sure 有驱动强度分辨率,但这是一个更高级的问题。还有 # 个延迟,但我们现在不用担心这些 - 如果您必须将它们放在 RTL 中,您可能做错了。

然而,reg 可以在任何时候分配给它,并且也可以进行非阻塞分配(值更改被推迟到时间片评估的末尾)。您甚至可能不会在每个时钟周期更新一个 reg,更不用说每个时间片(甚至每个时间片多次)。

但我们不深入讨论如何编写超出原始 Verilog 95 规范中包含的模拟器的内部细节。