FPGAに再入門しようと思いたちFPGAプログラミング大全Xilinx編第2版を頭からやっていく7日目
時期的にも良いので一人Advent Calendarで25日続ける
FPGAプログラミング大全ではCPUを作る方に行かないのでしばらくCPUの作り方と合わせてやっていくことにする
25日終了時の目標
4004等の実CPUの実装
目次
# | タイトル |
---|---|
01 | ツール導入 |
02 | 実機テスト下準備 |
03 | 実機テスト |
04 | クロック利用 |
05 | シミュレーション検証 |
06 | TD4 |
07 | TD4とりあえず実装 |
07 | TD4メモリ実装 |
09 | 未定 |
環境
【実装ボード】 Digilent Artix-7 35T Arty FPGA 評価キット
【OS】 Windows10
【IDE】 Vivado 2022.2
今日のゴール
TD4のverilog化
メモリ部分を作る
実際のコード
メモリ部分を作成してみたがシミュレータだと上手く動かないので明日以降デバッグ
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/12/02 22:34:10
// Design Name:
// Module Name: LED_Test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module LED_Test(
input CLK100MHZ,
input [3:0] sw,
output reg [3:0] led
);
reg [3:0] register_a;
reg [3:0] register_b;
reg carry;
reg finish_flag;
reg [3:0] program_counter;
reg [7:0] program;
reg [7:0] MEM[3:0];
reg [3:0] command;
reg [3:0] im;
initial begin
MEM[0] = 8'b00110001;
MEM[1] = 8'b01110001;
MEM[2] = 8'b00000001;
MEM[3] = 8'b01010001;
MEM[4] = 8'b10010000;
MEM[5] = 8'b00000000;
MEM[7] = 8'b00000000;
MEM[8] = 8'b00000000;
MEM[9] = 8'b00000000;
MEM[10] = 8'b00000000;
MEM[11] = 8'b00000000;
MEM[12] = 8'b00000000;
MEM[13] = 8'b00000000;
MEM[14] = 8'b00000000;
MEM[15] = 8'b00000000;
led = 4'b0000;
end
always @(posedge CLK100MHZ ) begin
// MEMからかprogram_counterのアドレスの命令をprogramに読み込む
program = MEM[program_counter];
command = program[7:4];
im = program[3:0];
// 命令 意味 オペコード
// ADD A, Im AレジスタにImを加算 0000
// ADD B, Im BレジスタにImを加算 0101
// MOV A, Im AレジスタにImを入れる 0011
// MOV B, Im BレジスタにImを入れる 0111
// MOV A, B AレジスタにBのデータを入れる 0001
// MOV B, A BレジスタにAのデータを入れる 0100
// JMP Im Imアドレスにジャンプ(絶対アドレスのみサポート) 1111
// INC Im キャリーフラグがない場合のみImアドレスにジャンプ(必ず加算命令の直後のみ実行) 1110
// IN A 入力ポートからAレジスタに転送 0010
// IN B 入力ポートからBレジスタに転送 0110
// OUT B Bレジスタのデータを出力ポートに転送 1001
// OUT Im データをそのまま出力ポートに転送 1011
if (finish_flag) begin
case (command)
4'b0000:begin
{ carry , register_a } = register_a + im;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b0101:begin
{ carry , register_b } = register_b + im;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b0011:begin
register_a = im;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b0111:begin
register_b = im;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b0001:begin
register_a = register_b;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b0100: begin
register_b = register_a;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b1111:begin
program_counter = im;
end
4'b1110:begin
if(!carry)
program_counter = im;
end
4'b0010:begin
register_a = sw;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b0110:begin
register_b = sw;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b1001:begin
led = register_b;
{ finish_flag, program_counter } = program_counter + 1;
end
4'b1011:begin
led = im;
{ finish_flag, program_counter } = program_counter + 1;
end
endcase
end
end
endmodule
今日はここまで