PSoCのシフトアウトによる32bitデータパス入力

32bit shift out inputting on PSoC Datapath
 
前回のシフト挿入の逆を行えば、CPU(C言語)で代入した32bitレジスト値をデータコンポーネントから出力させることができます。

C言語で対象のアドレスに値を代入するとデータコンポーネントの「f0_bus_stat」がHighになります。厳密にはf0_bus_statの4bit全てがHighになっているかを調べる必要がありますが、レジスタへの代入は一度に行われているので、1bitだけのチェックでも問題ありません。

データパスの「A0 WR SRC=F0」によってA0レジスタに値をコピーしてから、左シフトを行うと、各データブロックのはみ出したビットは「cy_psoc3_dp」の「so」パラメータに記録されます。出力された4bitのうち、so[3]が最上位ビットなので、この値を32bit分読み取ると、C言語で入力した32bit値を全て読み取ることになります。
sreg_out.v
`include "cypress.v"

module sreg_out (
	output  isr,
    output  data,
	input   clock
);

localparam PG_IDLE    = 3'b000;
localparam PG_COPY_F0 = 3'b001;
localparam PG_SHIFTOUT = 3'b010;

reg [2:0] pg_state;
reg [3:0] so_32;
reg [4:0] out_count;
reg f0_empty;
reg f0_not_empty;

always @(posedge clock)
begin
    case(pg_state)
    PG_IDLE:
    begin
        if(f0_not_empty)
        begin
            pg_state = PG_COPY_F0;
        end
    end
    PG_COPY_F0:
    begin
        out_count = 5'd0;
        pg_state = PG_SHIFTOUT;
    end
    PG_SHIFTOUT:
    begin
        out_count = out_count + 5'd1;
        if(out_count == 5'd0)
        begin
            pg_state = PG_IDLE;
        end
    end
    endcase
end

assign isr = f0_empty;
assign data = so_32[3];

cy_psoc3_dp32 #(
.cy_dpconfig_a({
}),
.cy_dpconfig_b({
}),
.cy_dpconfig_c({
}),
.cy_dpconfig_d({
}))dp(
    /*  input              */  .clk(clock),
    /*  input   [02:00]    */  .cs_addr(pg_state),
    /*  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  [03:00]    */  .f0_bus_stat(f0_not_empty),
    /*  output  [03:00]    */  .f0_blk_stat(f0_empty),
    /*  output  [03:00]    */  .f1_bus_stat(),
    /*  output  [03:00]    */  .f1_blk_stat(),
    /*  output  [03:00]    */  .so(so_32)
);

endmodule

今回のサンプルでは、32bit分シフトが完了するごとに割り込み信号を発生させ、そのタイミングで新しい値を代入しています。
値がそのままピン出力の状態になるため、LEDの点滅期間が短くなる→長くなるが繰り返されます。
main.c
#include "project.h"

int ppos = 0;

const uint32_t patterns[] = {
    0b11111111000000001111111100000000,
    0b11110000111100001111000011110000,
    0b11001100110011001100110011001100,
    0b10101010101010101010101010101010,
    0b11001100110011001100110011001100,
    0b11110000111100001111000011110000,
};

CY_ISR(OnInterruptSO)
{
    sreg_out_SetValue(patterns[ppos]);
    ppos++;
    if(ppos == 6) ppos = 0;
}

int main(void)
{
    CyGlobalIntEnable;

    so_isr_StartEx(OnInterruptSO);

    for(;;)
    {
    }
}
2019/06/19