超簡単なCPUのアーキテクチャ 超簡単なCPUの作り方(1) 超簡単なCPUの作り方(2) 超簡単なCPU:SFL記述の解説 | |
ここでは簡単なCPUを作成し、SFLの制御端子とステート文を理解します。
declare smallcpu {
input ram_to_cpu<16>;
output cpu_to_ram<16>;
instrin start;
output mem_adr<7>;
instrout mem_write;
instrout mem_read;
}
declare add7 {
input inA<7>;
input inB<7>;
output out<7>;
instrin add;
instr_arg add(inA,inB);
}
declare add16 {
input inA<16>;
input inB<16>;
output out<16>;
instrin add;
instr_arg add(inA,inB);
}
%d INST_OP inst<1:0>
%d INST_S inst<8:2>
%d INST_D inst<15:9>
%d INST_ADD 0b00
%d INST_CMP 0b10
%d INST_MOV 0b01
%d INST_BEQ 0b11
module smallcpu {
input ram_to_cpu<16>;
output cpu_to_ram<16>;
instrin start;
output mem_adr<7>;
instrout mem_write;
instrout mem_read;
reg inst<16>;
reg reg_A<16>;
reg reg_B<16>;
reg pc<7>;
reg_wr flag_zero;
add7 pcinc;
add16 adder;
instrself cmp_zero;
sel_v cmp_zero_in<16>;
sel_v cmp_zero_out;
instr_arg cmp_zero(cmp_zero_in);
instr_arg mem_read(mem_adr);
instr_arg mem_write(cpu_to_ram, mem_adr);
stage_name smallcpu_stg { task run(); }
instruct start generate
smallcpu_stg.run();
instruct cmp_zero par{
cmp_zero_out = ^/&cmp_zero_in;
}
stage smallcpu_stg {
state_name fetch, decode, ld_reg_a, ex_add, ex_cmp,
ex_mov, ex_beq;
first_state fetch;
state fetch par{
/* data path */
inst := mem_read(pc).ram_to_cpu;
pc := pcinc.add(6#0b0||0b1,
pc).out;
/* sequence control */
goto decode;
}
state decode par{
/* data path */
reg_B :=
mem_read(INST_S).ram_to_cpu;
/* sequence control */
any{
INST_OP == INST_ADD : goto
ld_reg_a; /* add instruction */
INST_OP == INST_CMP : goto
ld_reg_a; /* cmp instruction */
INST_OP == INST_MOV : goto
ex_mov; /* mov instruction */
(INST_OP ==
INST_BEQ)& flag_zero : goto ex_beq; /* branch taken */
(INST_OP ==
INST_BEQ)&(^flag_zero) : goto fetch; /* branch not taken */
}
}
state ld_reg_a par{
/* data path */
reg_B :=
mem_read(INST_S).ram_to_cpu;
/* sequence control */
any{
INST_OP == INST_ADD : goto
ex_add; /* add instruction */
INST_OP == INST_CMP : goto
ex_cmp; /* cmp instruction */
}
}
state ex_add par{
/* data path */
mem_write(adder.add(reg_A,
reg_B).out,INST_D);
flag_zero :=
cmp_zero(adder.out).cmp_zero_out;
/* sequence control */
goto fetch;
}
state ex_cmp par{
/* data path */
flag_zero := cmp_zero(reg_A@reg_B).cmp_zero_out;
/* sequence control */
goto fetch;
}
state ex_mov par{
/* data path */
mem_write(reg_B,INST_D);
/* sequence control */
goto fetch;
}
state ex_beq par{
/* data path */
pc := pcinc.add(6#0b0||0b1,INST_D).out;
inst :=
mem_read(INST_D).ram_to_cpu; /* instruction fetch */
/* sequence control */
goto decode;
}
}
}
|
|