SSブログ

PSoC 3 で、かけ算器を作った [PSoC]このエントリーを含むはてなブックマーク#

かけ算器

全国一千万人のデータパスファンの皆様、お待たせいたしました。 すっかり、公開を忘れていましたが、ついに、かけ算器までたどり着きました。 といっても、まだまだ、チューニングが必要ですね。 ひとまず、公開。

かけ算器の考え方

10倍増器のデータフロー

以前、「PSoC 3 で、16ビット演算器を作った」で定数倍のかけ算器を作りました。 このデータフローでは、アキュムレータのデータをシフトしながら、時々、データレジスタの値を足しこむことで、10倍の値を生成していました。 この「データレジスタの値を足しこむ」タイミングを制御すると、任意の倍数の「かけ算器」に改造することができます。


かけ算器のデータフロー

そのタイミングの制御の方法ですが、三つ目のデータパスを追加してシフトレジスタとして使い、その MSB の値にしたがって、データレジスタの値を足すか足さないかを決定します。 dp1 の A0 をシフトレジスタとして使用し、 dp0 の D0 レジスタに入った値を10倍にして dp0 の A0 に求める計算を行っています。

実際には、 dp1 に8ビットの値を入れてかけ算を行うため、かけ算の手順は、 STEP1 から STEP8 までが必要です。 このデータフローでは、下位4ビットの STEP5 から STEP8 までを記述しています。

シフトレジスタ部分の構成

シフトレジスタ部分の設定

シフトレジスタ dp1 で使用する機能そのものは、 dp0 の機能と揃えました。 そのため、ステートマシンと機能コードデコーダは、 dp0 と dp1 で同じものが使えます。

Verilog の記述

Verilog 記述は、一つの Verilog ファイルに三つのデータパスを記述しているので、かなり長くなってしまいました。 また、 dp0 で使用される機能コードの最下位ビットには、 dp1 の MSB を直接取り入れて、機能コードデコーダを簡略化しています。

//`#start header` -- edit after this line, do not edit this line
// ========================================
//
// Copyright noritan.org, 2013
// All Rights Reserved
// UNPUBLISHED, LICENSED SOFTWARE.
//
// CONFIDENTIAL AND PROPRIETARY INFORMATION
// WHICH IS THE PROPERTY OF NORITAN.ORG.
//
// ========================================
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 06/08/2013 at 16:32
// Component: Multiply16
module Multiply16 (
	output  drq,
	input   clock,
	input   en,
	input   reset
);

//`#start body` -- edit after this line, do not edit this line

// State code declaration
localparam      ST_IDLE     = 4'b0000;
localparam      ST_GET      = 4'b0001;
localparam      ST_STEP1    = 4'b1000;
localparam      ST_STEP2    = 4'b1001;
localparam      ST_STEP3    = 4'b1010;
localparam      ST_STEP4    = 4'b1011;
localparam      ST_STEP5    = 4'b1100;
localparam      ST_STEP6    = 4'b1101;
localparam      ST_STEP7    = 4'b1110;
localparam      ST_STEP8    = 4'b1111;
localparam      ST_WAIT     = 4'b0011;
localparam      ST_PUT      = 4'b0010;

// MSB part of Datapath function
localparam      CS_IDLE     = 2'b00;
localparam      CS_CLEAR    = 2'b01;
localparam      CS_SL       = 2'b10;
localparam      CS_ADD      = 2'b11;

// Wire declaration
wire[3:0]       state;          // State code
wire            f0_empty;       // DP1.F0 is EMPTY
wire[1:0]       f1_full;        // DP0.F1 is FULL
wire[1:0]       so;             // Shift out of DP0_A
wire[1:0]       co;             // Carry out of DP0_A
wire            dp1_msb;        // MSB of DP1

// Pseudo register
reg[1:0]        addr;           // MSB part of Datapath function
reg             d0_load;        // LOAD D0 from F0
reg             f1_load;        // LOAD F1

// State machine behavior
reg [3:0]       state_reg;
always @(posedge reset or posedge clock) begin
    if (reset) begin
                state_reg <= ST_IDLE;
    end else casez (state)
        ST_IDLE:
            if (en & ~f0_empty) begin
                state_reg <= ST_GET;
            end
        ST_GET:
                state_reg <= ST_STEP1;
        ST_STEP1:
                state_reg <= ST_STEP2;
        ST_STEP2:
                state_reg <= ST_STEP3;
        ST_STEP3:
                state_reg <= ST_STEP4;
        ST_STEP4:
                state_reg <= ST_STEP5;
        ST_STEP5:
                state_reg <= ST_STEP6;
        ST_STEP6:
                state_reg <= ST_STEP7;
        ST_STEP7:
                state_reg <= ST_STEP8;
        ST_STEP8:
                state_reg <= ST_WAIT;
        ST_WAIT:
            if (~f1_full[1] & ~f1_full[0]) begin
                state_reg <= ST_PUT;
            end
        /*ST_PUT*/ default:
                state_reg <= ST_IDLE;
    endcase
end
assign      state = state_reg;

// Internal control signals
always @(state) begin
    casez (state)
        ST_IDLE: begin
            addr    = CS_IDLE;
            d0_load = 1'b0;
            f1_load = 1'b0;
        end
        ST_GET: begin
            addr    = CS_CLEAR;
            d0_load = 1'b1;
            f1_load = 1'b0;
        end
        ST_STEP1, ST_STEP2, ST_STEP3, ST_STEP4,
        ST_STEP5, ST_STEP6, ST_STEP7: begin
            addr    = CS_SL;
            d0_load = 1'b0;
            f1_load = 1'b0;
        end
        ST_STEP8: begin
            addr    = CS_ADD;
            d0_load = 1'b0;
            f1_load = 1'b0;
        end
        ST_WAIT: begin
            addr    = CS_IDLE;
            d0_load = 1'b0;
            f1_load = 1'b0;
        end
        /*ST_PUT*/ default: begin
            addr    = CS_IDLE;
            d0_load = 1'b0;
            f1_load = 1'b1;
        end
    endcase
end

reg drq_reg;
always @(posedge clock) begin
    casez (state)
        ST_PUT:     drq_reg <= 1'b1;
        default:    drq_reg <= 1'b0;
    endcase
end
assign          drq = drq_reg;

cy_psoc3_dp16 #(.cy_dpconfig_a(
{
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM0:   IDLE0 : Do nothing*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM1:   IDLE1 : Do nothing*/
    `CS_ALU_OP__XOR, `CS_SRCA_A0, `CS_SRCB_A0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM2:   CLEAR0 : A0 <= ALU <= (A0 XOR A0);*/
    `CS_ALU_OP__XOR, `CS_SRCA_A0, `CS_SRCB_A0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM3:   CLEAR1 : A0 <= ALU <= (A0 XOR A0);*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP___SL, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM4:   SL0 : A0 <= ALU <= (A0) << 1;*/
    `CS_ALU_OP__ADD, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP___SL, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM5:   SL1 : A0<= ALU <= (A0 + D0) << 1;*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM6:   ADD0 : A0 <= ALU <= (A0);*/
    `CS_ALU_OP__ADD, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM7:   ADD1 : A0 <= ALU <= (A0 + D0);*/
    8'hFF, 8'h00,  /*CFG9:     */
    8'hFF, 8'hFF,  /*CFG11-10:     */
    `SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
    `SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
    `SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
    `SC_SI_A_DEFSI, /*CFG13-12:     */
    `SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0,
    1'h0, `SC_FIFO1_ALU, `SC_FIFO0_BUS,
    `SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
    `SC_FB_NOCHN, `SC_CMP1_NOCHN,
    `SC_CMP0_NOCHN, /*CFG15-14:     */
    10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
    `SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,
    `SC_WRK16CAT_DSBL /*CFG17-16:     */
}
), .cy_dpconfig_b(
{
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM0:   IDLE0 : Do nothing*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM1:   IDLE1 : Do nothing*/
    `CS_ALU_OP__XOR, `CS_SRCA_A0, `CS_SRCB_A0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM2:   CLEAR0 : A0, A1 <= ALU <= (A0 XOR A0);*/
    `CS_ALU_OP__XOR, `CS_SRCA_A0, `CS_SRCB_A0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM3:   CLEAR1 : A0, A1 <= ALU <= (A0 XOR A0);*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP___SL, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM4:   SL0 : A0 <= ALU <= (A0) << 1;*/
    `CS_ALU_OP__ADD, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP___SL, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM5:   SL1 : A0 <= ALU <= (A0 + A1) << 1;*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM6:   ADD0 : A0 <= ALU <= (A0);*/
    `CS_ALU_OP__ADD, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM7:   ADD1 : A0 <= ALU <= (A0 + A1);*/
    8'hFF, 8'h00,  /*CFG9:     */
    8'hFF, 8'hFF,  /*CFG11-10:     */
    `SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
    `SC_CI_A_CHAIN, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
    `SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
    `SC_SI_A_CHAIN, /*CFG13-12:     */
    `SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0,
    1'h0, `SC_FIFO1_ALU, `SC_FIFO0_BUS,
    `SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
    `SC_FB_NOCHN, `SC_CMP1_NOCHN,
    `SC_CMP0_NOCHN, /*CFG15-14:      */
    10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
    `SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,
    `SC_WRK16CAT_DSBL /*CFG17-16:     */
}
)) dp0(
        /*  input           */  .reset(reset),
        /*  input           */  .clk(clock),
        /*  input   [02:00] */  .cs_addr({addr[1:0], dp1_msb}),
        /*  input           */  .route_si(1'b0),
        /*  input           */  .route_ci(1'b0),
        /*  input           */  .f0_load(1'b0),
        /*  input           */  .f1_load(f1_load),
        /*  input           */  .d0_load(d0_load),
        /*  input           */  .d1_load(1'b0),
        /*  output  [01:00] */  .ce0(),
        /*  output  [01:00] */  .cl0(),
        /*  output  [01:00] */  .z0(),
        /*  output  [01:00] */  .ff0(),
        /*  output  [01:00] */  .ce1(),
        /*  output  [01:00] */  .cl1(),
        /*  output  [01:00] */  .z1(),
        /*  output  [01:00] */  .ff1(),
        /*  output  [01:00] */  .ov_msb(),
        /*  output  [01:00] */  .co_msb(),
        /*  output  [01:00] */  .cmsb(),
        /*  output  [01:00] */  .so(),
        /*  output  [01:00] */  .f0_bus_stat(),
        /*  output  [01:00] */  .f0_blk_stat(),
        /*  output  [01:00] */  .f1_bus_stat(),
        /*  output  [01:00] */  .f1_blk_stat(f1_full[1:0])
);

cy_psoc3_dp8 #(.cy_dpconfig_a(
{
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM0:   IDLE0 : Do nothing*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM1:   IDLE1 : Do nothing*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC___F0, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM2:   CLEAR0 : A0 <= F0;*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC___F0, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM3:   CLEAR1 : A0 <= F0;*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP___SL, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM4:   SL0 : A0 <= (A0 << 1);*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP___SL, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM5:   SL1 : A0 <= (A0 << 1);*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM6:   ADD0 : A0 <= A0;*/
    `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
    `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
    `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
    `CS_CMP_SEL_CFGA, /*CFGRAM7:   ADD1 : A0 <= A0;*/
    8'hFF, 8'h00,  /*CFG9:    */
    8'hFF, 8'hFF,  /*CFG11-10:    */
    `SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
    `SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
    `SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
    `SC_SI_A_DEFSI, /*CFG13-12:    */
    `SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0,
    1'h0, `SC_FIFO1_BUS, `SC_FIFO0_BUS,
    `SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
    `SC_FB_NOCHN, `SC_CMP1_NOCHN,
    `SC_CMP0_NOCHN, /*CFG15-14:    */
    10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
    `SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,
    `SC_WRK16CAT_DSBL /*CFG17-16:    */
}
)) dp1(
        /*  input                   */  .reset(reset),
        /*  input                   */  .clk(clock),
        /*  input   [02:00]         */  .cs_addr({addr[1:0], 1'b0}),
        /*  input                   */  .route_si(1'b0),
        /*  input                   */  .route_ci(1'b0),
        /*  input                   */  .f0_load(1'b0),
        /*  input                   */  .f1_load(1'b0),
        /*  input                   */  .d0_load(1'b0),
        /*  input                   */  .d1_load(1'b0),
        /*  output                  */  .ce0(),
        /*  output                  */  .cl0(),
        /*  output                  */  .z0(),
        /*  output                  */  .ff0(),
        /*  output                  */  .ce1(),
        /*  output                  */  .cl1(),
        /*  output                  */  .z1(),
        /*  output                  */  .ff1(),
        /*  output                  */  .ov_msb(),
        /*  output                  */  .co_msb(),
        /*  output                  */  .cmsb(),
        /*  output                  */  .so(dp1_msb),
        /*  output                  */  .f0_bus_stat(),
        /*  output                  */  .f0_blk_stat(f0_empty),
        /*  output                  */  .f1_bus_stat(),
        /*  output                  */  .f1_blk_stat()
);
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

かけ算器の使い方

これまでのかけ算器は、 dp0 の FIFO にデータが入ったら、それをトリガにして計算を開始していました。 今回は、 dp1 の FIFO への書き込みをトリガにしています。 そのため、かけ算器に値を書き込むときには、 dp0 への書き込みの後、 dp1 への書き込みをおこないます。

                for (i = 0; i < N_BATCH; i++) {
                    CY_SET_REG16(Multiply16_INPUT_PTR, alub[i]);
                    CY_SET_REG8(Multiply16_MULTIPLIER_PTR, alua[i]);
                }

かけ算の結果は、前回の「PSoC 3 で、 DMA 対応倍増器を作った」と同様に DMA で自動的に取り出されます。 プログラムの部分は、前回同様、計算結果を自動的に検証して、検証結果を LCD に表示させるようにしています。

プロジェクトアーカイブ

この記事を書くために作成したプロジェクトは、このファイルの拡張子を ZIP に変更して展開すると再現できます。

関連文献

開発編 ARM PSoCで作るMyスペシャル・マイコン (トライアルシリーズ)

開発編 ARM PSoCで作るMyスペシャル・マイコン (トライアルシリーズ)

  • 作者: 圓山 宗智
  • 出版社/メーカー: CQ出版
  • 発売日: 2013/12/24
  • メディア: 単行本

nice!(0)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。