0

I am supposed to design a simple 16 bit Moris Mano Computer, the components of which are Alu, Control Unit , Registers , and Bus.

The question is that: I am a little bit confused of the type of the variables. For example, should I use wire for D0,D1 ... D7 and T0,T1, .. , T7 , Or should I use reg.? And If I should use wire, how to assign value to them in the Always @(posedge clock) block?

A part of my code is as follows:

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

Moreover, The written code for T_Generator and D_Generator Tasks are as follows.

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

Thanks in advance.

Arman
  • 99
  • 9
  • 2
    Can you tell about about variables D0, D1, D2..? Are those architectural registers? If yes, then you should use declare them as reg. Also, wire cannot be driven inside a procedural block. It can only be used in a continuous assignment. – Rahul Behl Jun 01 '17 at 04:55
  • 2
    Have a look at [this answer here](https://stackoverflow.com/questions/36527671/when-should-i-use-reg-instead-of-wire/36527832#36527832). – Matthew Taylor Jun 01 '17 at 10:24
  • @RahulBehl T0,T1,...,T7 are cpu pulses in each of which special instruments are supposed to be run. For example Fetch and Decode phases are done in T0 and T1. I dont know whether they are registers or not. But I know that they must be changed in every positive edge of clock Using a counter. – Arman Jun 01 '17 at 12:20
  • 1
    Are the *_Generator inside the always block modules, functions or zero-time tasks? Modules are not allowed inside an always block. Tasks with time delays (`#`,`@`,`wait`,etc) are not synthesizable. – Greg Jun 01 '17 at 14:50
  • 1
    Also the `++` operator is not supported in Verilog. It is supported in SystemVerilog (the super set and successor of Verilog). However inside sequential block it is recommented to use non-blocking assignments (`<=`) instead of blocking (`=`) to prevent race condition. `++` is considered a blocking assignment. – Greg Jun 01 '17 at 15:00
  • @Greg Yeah you right I should change them to none-blocking. Actually, *_Generator are not modules but simple Tasks which could be seen in the post. (I updated The post). – Arman Jun 02 '17 at 07:46

1 Answers1

2

Short Answer:

They should be reg. And please reset your variables, don't use declare time initialisation if you plan to synthesize this.

Medium Answer:

If you are assigning in an always block use reg, else use wire. Please don't ever use declare time initialisation on wires. In valid uses of wires you will have a drive conflict that will confuse you in interesting ways.

Longer Answer:

At any instant is their value known without looking at the previous value? Wires are used for things like assign statements and connectivity because (from the simulator's perspective) there is no concept of memory in the wire. One simply looks at the RHS of the assign and knows what the LHS will be.Sure there is drive strength resolution, but that's a more advanced issue. There is also # delays but let's not worry about those for now - if you have to put those in RTL you are probably doing it wrong.

A reg however can be assigned to at any point and have non-blocking assignments as well (the value change is deferred to the end of the timeslice evaluation). You may not even update a reg every clock cycle, never mind every timeslice (or even multiple times per timeslice).

But let's not go into the details of the internals of how one might write a simulator beyond that contained in the original Verilog 95 spec.

Chris Hopkins
  • 961
  • 1
  • 7
  • 15