verilog 11 cpu 제작_1

2023. 3. 20. 19:13Verilog

디지털 시스템의 구성 

  • datapath 모듈 : 데이터 처리, 레지스터, 연산기, MUX
  • CU 모듈 : 제어신호 발생, 연산의 순서지정

RTL(Register Transfer Level)

  • reg단위의 연산
  • reg 데이터의 이동 / 처리
  • reg set, operation, sequence control

Micro-operation

  • reg에 저장된 데이터에 대한 기본연산 단위
  • 기본적으로 1 클럭동안에 수행됨

레지스터 전송 연산

마이크로 연산

이동, 산술, 논리, 시프트

논리 마이크로 연산

 

  • AND 마스크 :

  • OR 마스크 :

  • XOR 마스트

MUX를 이용한 전송 연결

  • 여러 개의 레지스터가 있을 때 그중 하나의 레지스터를 선택하기 위해 MUX를 사용
if(K1)
	R0 <= R1;
else if(K2) // = ((K1 == 0) && (K2 == 1))
	R0 <= R2;

블록 다이어그램
회로도

버스 전송 연결

 

싱글 버스

r1 <= r0가 선택이 됐다고 하면, R2가 선택할 수 있는 Source는 R0밖에 없음, 즉 R2 <= R0밖에 없음. 

하지만 MUX를 하나만 사용하기 때문에 사용하는 하드웨어가 적음

각 레지스터의 입력에 전용 MUX가 붙어있기 때문에 R1 <= R0인 상태에서 R2는 R1, R0같이 각각 다른 Source를 사용할 수 있다. 하지만 하드웨어를 더 많이 사용한다.

 

3상 버스를 사용한 연결

Data Path

 

ALU

산술연산장치

 

위의 회로를 사용하면 B의 값을 변형하여 FA로 여러 가지 일을 수행할 수 있다. 

 

논리연산장치

 

산술연산자에 비해 비교적 단순하게 사용할 수 있다. 

산술논리연산회로

Shifter

베릴로그의  << 연산

 

1비트 우 쉬프트

1비트 좌 쉬프트

Rotate 쉬프터

Barrel Shifter

  • 한 클럭에 n비트 이동 가능
  •  

제어 워드

  • 마이크로 연산의 데이터처리에 필요한 제어신호로 구성
  • 8개의 레지스터 파일을 가진 DataPath에대한 17비트 제어 워드 필드 :

DA : Data address

AA , BA : Source A address, Source B address

MB : Source B Mux select bit (코드의 상수 또는 레지스터 내부값)

FS : Function bit

MD : Fuction unit, Memory select bit

RW : Register file Read / Write

 

파이프라인

실습

 

register file 제작

module regFile #(parameter WD = 16, parameter REG_NUM = 8)(
    input Load_enable, clk, rst,
    input [WD-1 : 0] D_data,
    input [REG_NUM-1:0] Destination_select, //reg개수 8개
    input [REG_NUM-1:0] A_select, B_select,
    output [WD-1 : 0] Adata, Bdata
);
wire [WD-1 : 0] reg_to_mux [0:REG_NUM-1];


assign Adata = reg_to_mux[A_select];
assign Bdata = reg_to_mux[B_select];
reg [REG_NUM -1 : 0]Destination_decoder_out;

wire load_to_reg[0 : REG_NUM-1];


and(load_to_reg[0], Load_enable, Destination_decoder_out[0]);
and(load_to_reg[1], Load_enable, Destination_decoder_out[1]);
and(load_to_reg[2], Load_enable, Destination_decoder_out[2]);
and(load_to_reg[3], Load_enable, Destination_decoder_out[3]);
and(load_to_reg[4], Load_enable, Destination_decoder_out[4]);
and(load_to_reg[5], Load_enable, Destination_decoder_out[5]);
and(load_to_reg[6], Load_enable, Destination_decoder_out[6]);
and(load_to_reg[7], Load_enable, Destination_decoder_out[7]);




always @(Load_enable, Destination_select) begin
    case(Destination_select)
        3'd0 : Destination_decoder_out = 8'b00000001;
        3'd1 : Destination_decoder_out = 8'b00000010;
        3'd2 : Destination_decoder_out = 8'b00000100;
        3'd3 : Destination_decoder_out = 8'b00001000;
        3'd4 : Destination_decoder_out = 8'b00010000;
        3'd5 : Destination_decoder_out = 8'b00100000;
        3'd6 : Destination_decoder_out = 8'b01000000;
        3'd7 : Destination_decoder_out = 8'b10000000;
        default : Destination_decoder_out = 8'b0;
    endcase
end


reg_nbit #16 R0(.data_in(D_data), .en(load_to_reg[0]), .rst(rst), .clk(clk), .data_out(reg_to_mux[0]));
reg_nbit #16 R1(.data_in(D_data), .en(load_to_reg[1]), .rst(rst), .clk(clk), .data_out(reg_to_mux[1]));
reg_nbit #16 R2(.data_in(D_data), .en(load_to_reg[2]), .rst(rst), .clk(clk), .data_out(reg_to_mux[2]));
reg_nbit #16 R3(.data_in(D_data), .en(load_to_reg[3]), .rst(rst), .clk(clk), .data_out(reg_to_mux[3]));
reg_nbit #16 R4(.data_in(D_data), .en(load_to_reg[4]), .rst(rst), .clk(clk), .data_out(reg_to_mux[4]));
reg_nbit #16 R5(.data_in(D_data), .en(load_to_reg[5]), .rst(rst), .clk(clk), .data_out(reg_to_mux[5]));
reg_nbit #16 R6(.data_in(D_data), .en(load_to_reg[6]), .rst(rst), .clk(clk), .data_out(reg_to_mux[6]));
reg_nbit #16 R7(.data_in(D_data), .en(load_to_reg[7]), .rst(rst), .clk(clk), .data_out(reg_to_mux[7]));

    
endmodule
`timescale 1ns / 1ps

module reg_nbit #(parameter WD = 16)(
        input[WD-1 : 0] data_in,
        input clk, en, rst,
        output reg [WD-1 : 0] data_out
    );

    always @(posedge clk) begin
        if(rst)
            data_out <= 0;
        else if(en)
            data_out <= data_in;
    end
endmodule

`timescale 1ns / 1ps


module sim_mem;

reg clk, rst, Load_enable;
reg [15:0] data;
reg [7:0] d_sel, a_sel, b_sel;
wire[15:0] Adata, Bdata;

regFile #(16, 8) u1(.Load_enable(Load_enable), .clk(clk), .rst(rst), .D_data(data), .Destination_select(d_sel), .A_select(a_sel), .B_select(b_sel), .Adata(Adata), .Bdata(Bdata));

initial begin
clk = 0; rst = 1; Load_enable = 0; b_sel = 0; a_sel = 0; d_sel = 0;
#10 rst = 0;
#100;
#100 Load_enable = 1; d_sel = 3'd0; data = 16'h0000;
#100 Load_enable = 1; d_sel = 3'd1; data = 16'h1111;
#100 Load_enable = 1; d_sel = 3'd2; data = 16'h2222;
#100 Load_enable = 1; d_sel = 3'd3; data = 16'h3333;
#100 Load_enable = 1; d_sel = 3'd4; data = 16'h4444;
#100 Load_enable = 1; d_sel = 3'd5; data = 16'h5555;
#100 Load_enable = 1; d_sel = 3'd6; data = 16'h6666;
#100 Load_enable = 1; d_sel = 3'd7; data = 16'h7777;
#100 Load_enable = 0;
#150 a_sel = 3'd1; b_sel = 3'd0;
#150 a_sel = 3'd2; b_sel = 3'd3;
#150 a_sel = 3'd4; b_sel = 3'd5;
#150 a_sel = 3'd6; b_sel = 3'd7;
$finish;



end

always #50 clk = ~clk;
endmodule

8개의 레지스터에 200ns단위로 데이터를 넣은 후, a_출력과 b_출력을 150ns 단위로 엇갈리게 출력하였다. 결과가 잘 나오는것을 볼 수 있다. 

'Verilog' 카테고리의 다른 글

verilog 12 cpu설계-2  (0) 2023.03.27
verilog 10 FSM/ASM  (0) 2023.03.17
verilog 9 카운터 실습  (0) 2023.03.15
verilog7  (0) 2023.03.14
verilog 5  (0) 2023.03.13