PicoBlaze で LEDピコピコです。
PicoBlaze については、 http://www.xilinx.com/picoblaze に関連する情報と
PicoBlaze のアセンブラなどのダウンロードがあります。
- ロイヤリティフリーで使用可
- 8ビットマイコン
- 全ての命令は2クロックで実行される
- 16個のレジスタ / SCRACH PAD RAM(64Byte) / ROM(1K x 18bit)
マイコンは、アセンブラのソース(.psm)を KCPSM3.EXE でアセンブルします。
エラーが無ければHDLのソース VHDL と Verilog のソースが出力されるので
これをトップモジュールに組み込めば動くという寸法です。
xilinx からダウンロード出来る KCPSM3.ZIP の中には資料含めて一式入ってるので
大丈夫でしょう。また ug129 のユーザーガイドには日本語版PDF(日付古いですが…)
があるので、これもダウンロードしておけばいいと思います。
アセンブラのソース
ADDRESS 000
INIT00:
ENABLE INTERRUPT
MAIN00: LOAD s5, 00
MAIN90:
OUTPUT s5, 01 ; ポート1に出力する
ADD s5, 01
CALL DELAY1s
JUMP MAIN90
; ------------------------------------------------------------------------------
; -- 時間待ち
; -- 50Mhz = 20ns
; -- 1命令 2クロック = 40ns
; -- s0,s1,s2,s3
; ------------------------------------------------------------------------------
DELAY1us: LOAD s0, 17
DELAY1us00: SUB s0, 01
JUMP NZ, DELAY1us00
RETURN
DELAY100us: LOAD s1, 64
DELAY100us00: CALL DELAY1us
SUB s1, 01
JUMP NZ, DELAY100us00
RETURN
DELAY1ms: LOAD s2, 0A
DELAY1ms00: CALL DELAY100us
SUB s2, 01
JUMP NZ, DELAY1ms00
RETURN
DELAY20ms: LOAD s3, 14
DELAY20ms00: CALL DELAY1ms
SUB s3, 01
JUMP NZ, DELAY20ms00
RETURN
DELAY1s: LOAD s4, 32
DELAY1s00: CALL DELAY20ms
SUB s4, 01
JUMP NZ, DELAY1s00
RETURN
; ------------------------------------------------------------------------------
; -- 割り込みルーチン
; --
; ------------------------------------------------------------------------------
INTERRUPT:
; <<コード>>
RETURNI ENABLE
; ------------------------------------------------------------------------------
; -- 割り込みベクタ
; --
; ------------------------------------------------------------------------------
ADDRESS 3FF
JUMP INTERRUPT
</コード></code></pre>
<p>
Verilog のソース
</p>
<pre><code>
module main (
input wire CLK_50MHZ,
output wire [7:0] LED );
wire RESET;
wire CLKIN_IBUFG_OUT;
wire CLK0_OUT;
wire LOCKED_OUT;
wire [9:0] address ;
wire [17:0] instruction ;
wire [7:0] port_id ;
wire write_strobe, read_strobe, interrupt_ack ;
wire [7:0] out_port ;
wire [7:0] in_port ;
wire interrupt, reset, clk ;
user_reset reset00 (
.CLOCK(),
.RESET()
);
dcmsp00 dcmsp00 (
.CLKIN_IN(CLK_50MHZ),
.RST_IN(RESET),
.CLKIN_IBUFG_OUT(CLKIN_IBUFG_OUT),
.CLK0_OUT(CLK0_OUT),
.LOCKED_OUT(LOCKED_OUT)
);
kcpsm3 CPU00 (
.address(address),
.instruction(instruction),
.port_id(port_id),
.write_strobe(write_strobe),
.out_port(out_port),
.read_strobe(read_strobe),
.in_port(in_port),
.interrupt(interrupt),
.interrupt_ack(interrupt_ack),
.reset(RESET),
.clk(CLK0_OUT)
);
led CPU00LED (
.address(address),
.instruction(instruction),
.clk(CLK0_OUT)
);
outp_sel outp_sel (
.port_id(port_id),
.write_strobe(write_strobe),
.indata(out_port),
.otdata(LED)
);
endmodule
//
// Generate RESET PULSE
//
module user_reset (
input wire CLOCK,
output wire RESET );
SRL16 #(.INIT(16'h00FF)) // Initial Value of Shift Register
SRL16_inst (
.Q(RESET), // SRL data output
.A0(1'b1), // Select[0] input
.A1(1'b1), // Select[1] input
.A2(1'b1), // Select[2] input
.A3(1'b1), // Select[3] input
.CLK(CLOCK), // Clock input
.D(1'b0) // SRL data input
);
// End of SRL16_inst instantiation
endmodule
module outp_sel (
input wire port_id,
input wire write_strobe,
input wire [7:0] indata,
output reg [7:0] otdata
);
always @(posedge write_strobe)
begin
if(port_id == 1)
otdata = indata;
end
endmodule