作者yueayase (scrya)
看板Electronics
標題[問題] Verilog 作CPU
時間Fri Nov 26 02:13:59 2010
最近試著用 Computer Organization and Design(4th) 上的電路圖
做了一個Single Cycle 的CPU:
module CPU(
clk_i,
rst_i,
);
//I/O port
input clk_i;
input rst_i;
//Internal Signles
wire [31:0] pcout;
wire [31:0] pcadd;
wire [31:0] pcmuxout;
wire [31:0] pcmuxout1;
wire [31:0] pcmuxout2;
///////////////////////////////////////// instruction memory
wire [31:0] instrcout;
///////////////////////////////////////// reg file
//[4:0] regin1;
//[4:0] regin2;
wire [4:0] writereg;
wire [31:0] regdata;
wire [31:0] regout1;
wire [31:0] regout2;
///////////////////////////////////////// ALU
wire [31:0] datain;
//[31:0] aluresult;
wire aluzero;
wire [3:0] aluctrlout;
///////////////////////////////////////// sign extend
wire [31:0] signout;
///////////////////////////////////////// decoder
wire regdst;
wire regwrite;
wire branch;
wire alusrc;
wire [3:0] aluop;
wire [31:0] pcmuxin;
wire [31:0] shiftout;
wire [31:0] shiftout2;
//////////////////////////////////////// Data Memory
wire memread;
wire memwrite;
wire [31:0] memout;
wire andresult;
wire jump;
wire memtoreg;
//Greate componentes
ProgramCounter PC(
.clk_i(clk_i),
.rst_i(rst_i),
.pc_in_i(pcmuxout),
.pc_out_o(pcout)
);
// for program counter
Adder Adder1(
.src1_i(pcout),
.src2_i(4),
.sum_o(pcadd)
);
Instr_Memory IM(
.pc_addr_i(pcout),
.instr_o(instrcout)
);
// IM to Register file
MUX_2to1 #(.size(5)) Mux_Write_Reg(
.data0_i(instrcout[20:16]),
.data1_i(instrcout[15:11]),
.select_i(regdst),
.data_o(writereg)
);
assign shiftout2 = {pcout[31:28],instrcout[25:0]<<2}; // jump instruction
Reg_File RF(
.clk_i(clk_i),
.rst_i(rst_i),
.RSaddr_i(instrcout[25:21]),
.RTaddr_i(instrcout[20:16]),
.RDaddr_i(writereg),
.RDdata_i(regdata),
.RegWrite_i(regwrite),
.RSdata_o(regout1),
.RTdata_o(regout2)
);
Decoder Decoder(
.instr_op_i(instrcout[31:26]),
.RegWrite_o(regwrite),
.ALU_op_o(aluop),
.ALUSrc_o(alusrc),
.RegDst_o(regdst),
.Branch_o(branch),
.Jump_o(jump),
.MemRead_o(memread),
.MemWrite_o(memwrite),
.MemtoReg_o(memtoreg)
);
ALU_Ctrl AC(
.funct_i(instrcout[5:0]),
.ALUOp_i(aluop),
.ALUCtrl_o(aluctrlout)
);
Sign_Extend SE(
.data_i(instrcout[15:0]),
.data_o(signout)
);
// Choose RT or sign extension for ALU
MUX_2to1 #(.size(32)) Mux_ALUSrc(
.data0_i(regout2),
.data1_i(signout),
.select_i(alusrc),
.data_o(datain)
);
ALU ALU(
.src1_i(regout1),
.src2_i(datain),
.ctrl_i(aluctrlout),
.sha(instrcout[10:6]),
.result_o(regdata),
.zero_o(aluzero)
);
// for branch instruction
Adder Adder2(
.src1_i(pcadd),
.src2_i(shiftout),
.sum_o(pcmuxin)
);
Shift_Left_Two_32 Shifter(
.data_i(signout),
.data_o(shiftout)
);
assign andresult= aluzero & branch;
MUX_2to1 #(.size(32)) Mux_PC_Source(
.data0_i(pcadd),
.data1_i(pcmuxin),
.select_i(andresult),
.data_o(pcmuxout1)
);
// for jump instruction
MUX_2to1 #(.size(32)) Mux_PC_Source3(
.data0_i(pcmuxout1),
.data1_i(shiftout2),
.select_i(jump),
.data_o(pcmuxout)
);
Data_Memory Data_Memory(
.clk_i(clk_i),
.addr_i(regdata),
.data_i(regout2),
.MemRead_i(memread),
.MemWrite_i(memwrite),
.data_o(memout)
);
// for data memory to RL(Write back to register)
MUX_2to1 #(.size(32)) Mux_PC_Source2(
.data0_i(regdata),
.data1_i(memout),
.select_i(memtoreg),
.data_o(regdata)
);
endmodule
==========================================================================
這只是CPU的架構,各元件的沒辦法放上來
在排除元件指令錯誤的情況下,這些裝置放的位置(順序)是正確的嗎?
因為感覺上Verilog很重視這些東西放的順序
另外 在assign shiftout2 = {pcout[31:28],instrcout[25:0]<<2};的地方
為什麼不可以用:
Shift_Left_Two_32 Shifter(
.data_i({6'b000000, instrcout[25:0]}),
.data_o(shiftout2)
);
assign shiftout2 = {pcout[31:28],shiftout2[27:0]};
來表示jump instruction的前半段
因為我是新手,所以不太清楚Verilog的程式設計架構
希望一些大師幫我解答
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.251.181.92
※ 編輯: yueayase 來自: 111.251.181.92 (11/26 02:34)
1F:→ klorc:你可以先開新檔...從小的conponent寫tb測試 11/26 09:23
2F:→ bakerly:verilog不是寫C, MODULE放的順序不會影響結果 11/27 09:09
3F:→ bakerly:寫錯..是instance不是module 11/27 09:12
4F:→ yueayase:謝謝回答 11/27 23:08