前回はアキュムレータマシンについて学習したのですが、まったく理解できませんでした。
プログラムがどのように動作しているのかよくわかりません。
ソースコードは以下のとおりです。
`timescale 1ns / 1ps
module ALU(A,B,COM,ALUOUT);
parameter DWIDTH = 8;
parameter NOP = 3'b000,LD=3'b001,AND=3'b010,OR=3'b011,SL=3'b100,
SR=3'b101,ADD=3'b110,SUB=3'b111;
input[DWIDTH-1:0] A;
input[DWIDTH-1:0] B;
input[2:0] COM;
output[7:0] ALUOUT;
assign ALUOUT =alu(A,B,COM);
function[DWIDTH-1:0] alu;
input[DWIDTH-1:0] A;
input[DWIDTH-1:0] B;
input[2:0] COM;
begin
case(COM)
NOP: alu = A;
LD: alu = B;
AND:alu = A & B;
OR: alu = A | B;
SL: alu = A << 1;
SR: alu = A >> 1;
ADD: alu = A + B;
SUB: alu = A - B;
default: alu = 8'bxxxx_xxxx;
endcase
end
endfunction
endmodule
`timescale 1ns / 1ps
module CTRL(CLK, RESET_N, STATE);
parameter INIT = 3'b001, IF = 3'b010, EXEC = 3'b100;
input CLK;
input RESET_N;
output [2:0] STATE;
reg[2:0] STATE;
always@(posedge CLK or negedge RESET_N)begin
if(RESET_N == 0)
STATE <= INIT;
else
case(STATE)
INIT: STATE <= IF;
IF: STATE <= EXEC;
EXEC: STATE <= IF;
default: STATE <= IF;
endcase
end
endmodule
`timescale 1ns / 1ps
module MEM16_8(CLK, WE, ADDRESS, DIN, DOUT, reset_n_i);
// Implemented with a register file.
parameter ASIZE = 4, DSIZE = 8;
parameter two4 = 16; //2^4 = 16;
input CLK;
input WE;
input reset_n_i;
input [ASIZE-1:0] ADDRESS;
input [DSIZE-1:0] DIN;
output [DSIZE-1:0] DOUT;
reg [DSIZE-1:0] DOUT;
reg [DSIZE-1:0] MEMCELL [0:two4-1];
integer i;
always @(negedge CLK or negedge reset_n_i)begin
if(reset_n_i == 1'b0)begin
MEMCELL[0] = 8'b0000_0010; // 2
MEMCELL[1] = 8'b0000_0000; // 0
MEMCELL[2] = 8'b0000_1000; // 8
MEMCELL[3] = 8'b0000_0000; //
MEMCELL[4] = 8'b0000_0000; //
MEMCELL[5] = 8'b0000_0000; // Answer
MEMCELL[6] = 8'b0000_0000;
MEMCELL[7] = 8'b0000_0000;
MEMCELL[8] = 8'b0000_0000;
MEMCELL[9] = 8'b0000_0000;
MEMCELL[10] = 8'b0000_0000;
MEMCELL[11] = 8'b0000_0000;
MEMCELL[12] = 8'b0000_0000;
MEMCELL[13] = 8'b0000_0000;
MEMCELL[14] = 8'b0000_0000;
MEMCELL[15] = 8'b0000_0000;
end
else begin
if(WE == 1'b1)begin // WRITE
MEMCELL[ADDRESS] <= DIN;
end
else begin
DOUT <= MEMCELL[ADDRESS];
end
end
end
endmodule
`timescale 1ns / 1ps
//
module MUX4BITS(D0, D1, SEL, Y);
input [3:0] D0;
input [3:0] D1;
input SEL;
output [3:0] Y;
assign Y = SEL ? D1 : D0;
endmodule
`timescale 1ns / 1ps
module PC(CLK, RESET_N, CE, Y);
parameter DSIZE = 4;
input CLK;
input RESET_N;
inout CE;
output [DSIZE-1:0] Y;
reg[DSIZE-1:0] pc;
always@(posedge CLK or negedge RESET_N)begin
if(RESET_N == 0)
pc <= 4'b0000;
else if(pc!=4'b1111 && CE == 1)
pc <= pc + 4'b0001;
end
assign Y = pc;
endmodule
`timescale 1ns / 1ps
module REG8(CLK, RESET_N, CE, DIN, DOUT);
parameter DSIZE = 8;
input CLK;
input RESET_N;
input CE; //Clock Enabele
input [DSIZE-1:0] DIN;
output [DSIZE-1:0] DOUT;
reg [DSIZE-1:0] r;
always@(posedge CLK or negedge RESET_N)begin
if(RESET_N==0)
r <= 8'b0000_0000;
else if(CE==1)
r <= DIN;
end
assign DOUT = r;
endmodule
`timescale 1ns / 1ps
module ROM16_8(ADDRESS, DOUT);
// Instruction Memory coded by Y. Iguchi.
parameter DSIZE = 8;
parameter NOP=4'b0000,LD=4'b0001,AND=4'b0010,OR=4'b0011;
parameter SL=4'b0100,SR=4'b0101,ADD=4'b0110,SUB=4'b0111;
parameter ST=4'b1000;
input [3:0] ADDRESS;
output [DSIZE-1:0] DOUT;
function [DSIZE-1:0] rom;
input [3:0] address;
case(address)
// (X-Z)AND (Y+Z)
// datamem[0]: X
// datamem[1]: Y
// datamem[2]: Z
// datamem[3]: (X-Z) AND (Y+Z)
0: rom = {LD, 4'b0000}; //LD 0 0001_0000 10H
1: rom = {SUB,4'b0010}; //SUB 2 0111_0010 72H
2: rom = {ST, 4'b0011}; //ST 3 1000_0011 83H
3: rom = {LD, 4'b0001}; //LD 1 0001_0001 11H
4: rom = {ADD,4'b0010}; //ADD 2 0110_0010 62H
5: rom = {AND,4'b0011}; //AND 3 0010_0011 23H
6: rom = {ST, 4'b0011}; //ST 3 1000_0011 83H
7: rom = {NOP,4'b0000}; //NOP
8: rom = {NOP,4'b0000}; //NOP
9: rom = {NOP,4'b0000}; //NOP
10: rom = {NOP,4'b0000}; //NOP
11: rom = {NOP,4'b0000}; //NOP
12: rom = {NOP,4'b0000}; //NOP
13: rom = {NOP,4'b0000}; //NOP
14: rom = {NOP,4'b0000}; //NOP
15: rom = {NOP,4'b0000}; //NOP
default: rom = {NOP,4'b0000}; //NOP
endcase
endfunction
assign DOUT = rom(ADDRESS);
endmodule
`timescale 1ns / 1ps
//
module TOP(CLK, RESET_N, MODE, SW, LED
//,PC, ACC, IR, STATE
);
input CLK;
input RESET_N;
input MODE;
input [3:0] SW;
output [7:0] LED;
// output [3:0] PC;
// output [7:0] ACC;
// output [7:0] IR;
// output [2:0] STATE;
wire [2:0] state;
wire [3:0] pc_dout;
wire [7:0] inst_mem_dout, ir_dout;
wire [7:0] acc_dout, alu_out, data_mem_dout;
wire [3:0] mux_out;
wire acc_ce, ir_ce, pc_ce, we;
assign acc_ce = state[2];
assign ir_ce = state[1];
assign pc_ce = state[1];
assign we = ir_dout[7];
// assign PC = pc_dout;
// assign ACC = acc_dout;
// assign IR = ir_dout;
// assign STATE = state;
CTRL ctrl(.CLK(CLK), .RESET_N(RESET_N), .STATE(state));
PC pc(.CLK(CLK), .RESET_N(RESET_N), .CE(pc_ce), .Y(pc_dout));
REG8 acc(.CLK(CLK),.RESET_N(RESET_N),.CE(acc_ce),.DIN(alu_out),.DOUT(acc_dout)); //Acc
REG8 ir(.CLK(CLK),.RESET_N(RESET_N),.CE(ir_ce),.DIN(inst_mem_dout),.DOUT(ir_dout)); //IR
ROM16_8 inst_mem(.ADDRESS(pc_dout),.DOUT(inst_mem_dout));
MUX4BITS mux(.D0(ir_dout[3:0]),.D1(SW),.SEL(MODE),.Y(mux_out));
MEM16_8 data_mem(.CLK(CLK),.WE(we),.ADDRESS(mux_out),.DIN(acc_dout),.DOUT(data_mem_dout),.reset_n_i(RESET_N));
ALU alu8(.A(acc_dout),.B(data_mem_dout),.COM(ir_dout[6:4]),.ALUOUT(alu_out));
assign LED = data_mem_dout;
endmodule
課題としてトップモジュールのブロック図を描くようにいわれたのですが、まずプログラムがどのように動作しているのか理解できないので困ってます。
このプログラムについて詳しく教えていただけないでしょうか?