Как преодолеть «предупреждение: порт 8 (назначение) инструкции_регера ожидает 8 битов, получил 1». в верилоге? - PullRequest
0 голосов
/ 09 января 2019

Моя задача - реализовать процессор с памятью данных, используя verilog. Инструкции жестко запрограммированы (32-битные инструкции). Я завершил вставку памяти данных. Для загрузки и хранения инструкций Но когда все выполнено, я получаю: «Предупреждение: порт 8 (назначение) инструкции_рег ожидает 8 бит, получил 1».

Это код verilog для архитектуры набора команд

<pre><code>
//ALU created

module ALU(out,DATA1,DATA2,Select); //module for ALU
input [7:0]DATA1,DATA2;//8 bit data inputs
    input [2:0] Select;//three bit selection 
    output [7:0]out;//8 bit data output
    reg out;//outputt register
    always@(DATA1,DATA2,Select)
    begin
        case(Select)
            3'b000: out=DATA1;//forward
            3'b001: out=DATA1+DATA2;//add
            3'b010: out=DATA1 & DATA2;//and
            3'b011: out=DATA1| DATA2; //or

        endcase
    end

endmodule
//here no need of its test bench

//registerFile created in part2
module Register(clk,busy_wait,INaddr,IN,OUT1addr,OUT1,OUT2addr,OUT2);
    input clk;
 input [2:0] INaddr;
 input [7:0] IN;
 input [2:0] OUT1addr;
 output[7:0] OUT1;
 input [2:0] OUT2addr;
 output[7:0] OUT2;
 input busy_wait;       //new

reg [7:0] reg0, reg1, reg2, reg3,reg4,reg5,reg6,reg7;
assign OUT1 =   OUT1addr == 0 ? reg0 :
                OUT1addr == 1 ? reg1 :
                OUT1addr == 2 ? reg2 :
                OUT1addr == 3 ? reg3 :
                OUT1addr == 4 ? reg4 :
                OUT1addr == 5 ? reg5 :
                OUT1addr == 6 ? reg6 :
                OUT1addr == 7 ? reg7 : 0;


assign OUT2 =   OUT2addr == 0 ? reg0 :
                OUT2addr == 1 ? reg1 :
                OUT2addr == 2 ? reg2 :
                OUT2addr == 3 ? reg3 :
                OUT2addr == 4 ? reg4 :
                OUT2addr == 5 ? reg5 :
                OUT2addr ==  6? reg6 :
                OUT2addr == 7 ? reg7 : 0;


 always @(negedge clk) 
    begin
    //check weather it is not busy
    if (!busy_wait) begin
        case(INaddr)
            3'b000: reg0=IN;
            3'b001: reg1=IN;
            3'b010: reg2=IN;
            3'b011: reg3=IN;
            3'b100: reg4=IN;
            3'b101: reg5=IN;
            3'b110: reg6=IN;
            3'b111: reg7=IN;
        endcase
     end
     end 
endmodule

//we need control unit

//we need twos compliment when substractor is called

module twos_compliment(IN,OUT);     //twos complement
    input [7:0] IN;
    output signed [7:0] OUT;

    assign OUT=-IN;
endmodule

//multiplexer is used to select value or compliment
module multiplex(IN1,IN2,OUT,SELECT);       //multiplexer
    input [7:0] IN1,IN2;
    input SELECT;
    output [7:0] OUT;

    assign OUT = (SELECT) ? IN2 : IN1 ;

endmodule

//program counter is needed
module counter(clk,reset,busy_wait,addr);       //module program counter
    input clk,reset;
    output [31:0] addr;
    reg addr;
    input busy_wait;
//in hardcoded instructions Memroy start is hexadecimal 00000000 
    always @(reset) begin
        addr = 32'h00000000;
    end

    always @(negedge clk) begin
    //now we have to check busy wait also
    if(~reset && !busy_wait)
            begin
        addr = addr + 1;//addr is incremented by 1
        end

    else if (busy_wait) begin
        addr <= addr ;
    end
    end
endmodule


//control unit
//input should be instruction opcode
//output should be select for alu and input to muxes

module CU(Instruction,busy_wait,opcode,SELECT,mulx1,mulx2,memRead,memWrite,regWrite,Destination,address);   //control unit
    input [7:0] opcode;
    input [31:0] Instruction;
    input [7:0] Destination;
    //input [31:0] Instruction_code;//to extract load or Store Adress the Instruction code [23-16]
    output [2:0] SELECT;
    output mulx1,mulx2;
    input busy_wait; //new
     output memRead; //new
     output memWrite;//new
         output regWrite;//new
         output [7:0] address;//new
         reg mulx1,mulx2,memRead,memWrite,regWrite,address;


    assign SELECT = opcode [2:0]; //select should be opcodes last three bits for alu
    always @(opcode) begin
        case(opcode)
            8'b00000000:begin   //for mov   
                mulx1 = 1'b1;
                mulx2 = 1'b0;
                end
            8'b00000001:begin   //for add   
                mulx1 = 1'b1;
                mulx2 = 1'b0;
                end
            8'b00001001:begin   //sub   
                mulx1 = 1'b1;
                mulx2 = 1'b1;
                end
            8'b00000010:begin   //and   
                mulx1 = 1'b1;
                mulx2 = 1'b0;
                end
            8'b00000011:begin   //or    
                mulx1 = 1'b1;
                mulx2 = 1'b0;
                end
            8'b00001000:begin   //for loadImmediate 
                mulx1 = 1'b0;
                end

                /*4'b0101:
            begin
                memRead = 1'b0;
                memWrite = 1'b1;
                address = instruction[23:16];
                $display("oper = store");
            end                     
            // store to memory
                */

            8'b00000101:begin   //for store to Data memory(selected 00000101)   
                memRead = 1'b0;
                memWrite = 1'b1;
                assign address = Destination;
                mulx1 = 1'b1;
                mulx2 = 1'b1;
                end
                /*4'b0100:
            // load from memory 
            begin
                memWrite = 1'b0;
                memRead = 1'b1;
                address = instruction[7:0];
                $display("oper = load");    
            end

                */

            8'b00000100:begin   //for load To register From Data memory (selected 00000100)
                memWrite = 1'b0;
                memRead = 1'b1;
                assign address = Instruction[7:0];
                mulx1 = 1'b1;
                mulx2 = 1'b1;
                end

                default : 
        begin
            memWrite = 1'b0;
            memRead = 1'b0; 
        end     
        endcase

    end
endmodule
//instruction memory 32 bits instead of memory
module instruction_mem(Read_addr,Instruction_code);
    output [31:0] Instruction_code;
    reg Instruction_code;
    input [31:0] Read_addr;

    always @(Read_addr) begin
        case(Read_addr)

            /*32'h00000000: Instruction_code = 32'b00001000 00000 100 00000000 11111111;// loadi 4 X 0xFF(255)
            32'h00000001: Instruction_code = 32'b00001000 00000 110 00000000 10101010;// loadi 6 X 0xAA(170)

            32'h00000002: Instruction_code = 32'b00001000 00000 011 00000000 10111011;// loadi 3 X 0xBB(187)

            32'h00000003: Instruction_code = 32'b00000001 00000 101 00000 110 00000 011;// add   5 6 3

            32'h00000004: Instruction_code = 32'b00000010 00000 001 00000 100 00000 101;// and   1 4 5

            32'h00000005: Instruction_code = 32'b00000011 00000 010 00000 001 00000 110;// or    2 1 6

            32'h00000006: Instruction_code = 32'b00000000 00000 111 00000 000 00000 010;// mov   7 x 2

            32'h00000007: Instruction_code = 32'b00001001 00000 100 00000 111 00000 011;// sub   4 7 3
            32'h00000008: Instruction_code = 32'b00000101 00000000 00000 000 00000 100;     // store 0, X, 4
            32'h00000009: Instruction_code = 32'b00000100 00000101 00000 000 00000 000;     // load 5, X, 0*/


            /*Hard coded instructions for Processor without memry is commented*/
            /*32'h00000000: Instruction_code = 32'b00001000000001000000000011111111;// loadi 4 X 0xFF(255)
            32'h00000001: Instruction_code = 32'b00001000000001100000000010101010;// loadi 6 X 0xAA(170)
            32'h00000002: Instruction_code = 32'b00001000000000110000000010111011;// loadi 3 X 0xBB(187)
            32'h00000003: Instruction_code = 32'b00000001000001010000011000000011;// add   5 6 3
            32'h00000004: Instruction_code = 32'b00000010000000010000010000000101;// and   1 4 5
            32'h00000005: Instruction_code = 32'b00000011000000100000000100000110;// or    2 1 6
            32'h00000006: Instruction_code = 32'b00000000000001110000000000000010;// mov   7 x 2
            32'h00000007: Instruction_code = 32'b00001001000001000000011100000011;// sub   4 7 3*/


            //new instructions
            32'h00000000: Instruction_code = 32'b00000101000000000000000000000100;      // store 0, X, 4
            32'h00000001: Instruction_code = 32'b00000100000001010000000000000000;      // load 5, X, 0


        endcase
    end
endmodule



//inside the control unit a opcode should be divided in instruction reg

module instruction_reg(Instruction,clk,OPCODE,OUT1addr,OUT2addr,INaddr,Immediate,Destination);
    input [31:0] Instruction;
    input clk;
    output[2:0] OUT1addr,OUT2addr,INaddr;
    output [7:0] OPCODE,Immediate,Destination;


    assign INaddr = Instruction[18:16];
    assign OPCODE = Instruction[31:24];//31-24 taken declared as op code
    assign Immediate = Instruction[7:0];//immediate value is 7-0
    assign OUT1addr = Instruction[2:0]; //output1addr addredd of output data by the registerFile
    assign OUT2addr = Instruction[10:8];
    assign Destination=Instruction[23:16];//new
endmodule

//data memory
module data_mem(
    clk,
    rst,
    read,
    write,
    address,
    write_data,
    read_data,
    busy_wait
);
input           clk;
input           rst;
input           read;
input           write;
input[7:0]      address;
input[7:0]      write_data;
output[7:0]     read_data;
output          busy_wait;

reg[7:0]     read_data;
reg busy_wait,clkMem=1'b0;
integer  i;

// Declare memory 256x8 bits 
reg [7:0] memory_array [255:0];
//reg [7:0] memory_ram_q [255:0];



always @(posedge rst)
begin
    if (rst)
    begin
        for (i=0;i<256; i=i+1)
            memory_array[i] <= 0;
    end
end

always #1 clkMem = ~clkMem;

always @(posedge clkMem)
begin
    if (write && !read && !busy_wait)
    begin
        busy_wait <= 1;
        // artificially delay 100 cycles
        repeat(10)
        begin
        @(posedge clk);
        end
        $display("writing to memory");
        memory_array[address] = write_data;
        busy_wait <= 0;
    end
    if (!write && read && !busy_wait)
    begin
        busy_wait <= 1;
        // artificially delay 100 cycles
        repeat(10)
        begin
        @(posedge clk);
        end
        $display("reading from memory");
        read_data = memory_array[address];
        busy_wait <= 0;
    end
end

endmodule


//test bench

module for_processor_test();
    wire [2:0] SELECT,OUT1addr,OUT2addr,INaddr;
    wire mux1OUT,mux2OUT;
    reg clk,reset,reset_reg;
    wire [31:0] Read_addr,Instruction_code;
    wire [7:0] OPCODE,Immediate,OUT1,OUT2,RESULT,twosComplement,mux2out,mux1out;


    counter c1(clk,reset,busy_wait,Read_addr);
    instruction_mem instruct_mem1(Read_addr,Instruction_code);
    instruction_reg instruct_reg1(Instruction_code,clk,OPCODE,OUT1addr,OUT2addr,INaddr,Immediate,Destination);
    CU cu1(Instruction_code,busy_wait,OPCODE,SELECT,mulx1,mulx2,memRead,memWrite,regWrite,Destination,address);
    //CU cu1(Instruction_code,busy_wait,opcode,SELECT,mulx1,mulx2,memRead,memWrite,regWrite,address);
    //CU myCU(busy_wait,instruction, out_addr1, out_addr2, in_addr, select, data2_compli_control, immediate_control, immediate_value, memRead,memWrite,regWrite,address);

    //(opcode,SELECT,mulx1,mulx2,memRead,memWrite,regWrite)
    Register regfile(clk,busy_wait,INaddr,RESULT,OUT1addr,OUT1,OUT2addr,OUT2);
    twos_compliment tcmplmnt(OUT1,twosComplement);
    multiplex mulx2(OUT1,twosComplement,mux2out,mux2OUT);
    multiplex mulx1(Immediate,mux2out,mux1out,mux1OUT);
    ALU alu(RESULT,mux1out,OUT2,SELECT);
        data_mem mdata_mem(clk,rst,memRead,memWrite,address,write_data,read_data,busy_wait);
    always #10 clk = ~clk;

    initial begin

        clk = 0;
        reset = 1;
        reset = 0;
        reset_reg = 1;
        reset_reg = 0;
        #160 

        $finish;
    end

    initial begin
        while(1) begin
        #10 $display("INSTRUCTION=%b RESULT=%d clock=%d",Instruction_code,RESULT,clk);
        //#20 $display("INSTRUCTION=%b RESULT=%d clock=%d",Instruction_code,RESULT,clk);
        end
    end
endmodule

1 Ответ

0 голосов
/ 09 января 2019

В модуле for_processor_test вы не объявили Destination. Verilog - довольно либеральный язык (по умолчанию), поэтому он неявно объявил wire с именем Destination для вас. Однако этот неявный провод будет иметь ширину всего 1 бит. Следовательно, ваше сообщение об ошибке.

Если вы хотите ужесточить это либеральное поведение (вы делаете это), то вы можете добавить эту директиву компиляции:

`default_nettype none

Если бы вы сделали это, вы бы получили более информативное сообщение об ошибке.

...