Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ACRiブログ "FPGA をもっと活用するために IP コアを使ってみよう (4)" のコードスニペット
`default_nettype none
module bram_example_top (
input wire CLK,
input wire RST,
output logic DATA_OUT
);
logic [7:0] DATA_IN;
logic WE;
logic BUSY;
serial_send serial_send_i(.CLK(CLK),
.RST(RST),
.DATA_IN(DATA_IN),
.WE(WE),
.DATA_OUT(DATA_OUT),
.BUSY(BUSY)
);
logic [13:0] A;
logic [7:0] Q;
bram_example_vio bram_example_i (.CLKA(CLK),
.CLKB(CLK),
.RST(RST),
.A(A),
.Q(Q)
);
bram_to_uart bram_to_uart_i(.CLK(CLK),
.RST(RST),
.BUSY(BUSY),
.DATA_IN(DATA_IN),
.WE(WE),
.A(A),
.Q(Q));
endmodule // bram_example_top
`default_nettype wire
`default_nettype none
module bram_example_vio (
input wire CLKA,
input wire CLKB,
input wire RST,
input wire [13:0] A,
output logic [7:0] Q
);
logic ena, enb;
logic [0:0] wea, web;
logic [13:0] addra, addrb;
logic [7:0] dina, dinb;
logic [7:0] douta, doutb;
blk_mem_gen_0 blk_mem_gen_0_i (
.clka(CLKA),
.ena(ena),
.wea(wea),
.addra(addra),
.dina(dina),
.douta(douta),
.clkb(CLKB),
.enb(enb),
.web(web),
.addrb(addrb),
.dinb(dinb),
.doutb(doutb)
);
// Port A
assign ena = 1'b1;
assign dinb = 8'h0;
// Port B
assign enb = 1'b1;
assign web = 1'b0; // read-only
assign dinb = 8'h0;
assign addrb = A;
assign Q = doutb;
(* KEEP *) logic [7:0] probe_in0;
(* KEEP *) logic probe_out0, probe_out0_r;
(* KEEP *) logic [7:0] probe_out1;
(* KEEP *) logic [15:0] probe_out2;
vio_0 vio_0_i (
.clk(CLKA),
.probe_in0(probe_in0),
.probe_out0(probe_out0),
.probe_out1(probe_out1),
.probe_out2(probe_out2)
);
always_ff @(posedge CLKA) begin
probe_out0_r <= probe_out0;
if(probe_out0_r == 0 && probe_out0 == 1) begin
wea <= 1'b1;
end else begin
wea <= 1'b0;
end
end
assign dina = probe_out1;
assign addra = probe_out2[13:0];
assign probe_in0 = douta;
endmodule // bram_example
`default_nettype wire
`default_nettype none
module bram_to_uart
(
input wire CLK,
input wire RST,
input wire BUSY,
output logic WE,
output logic [7:0] DATA_IN,
output logic [13:0] A,
input wire [7:0] Q
);
typedef enum {
STATE_IDLE,
STATE_WAIT,
STATE_SEND, STATE_SEND_WAIT,
STATE_SEND_CR, STATE_SEND_CR_WAIT,
STATE_SEND_LF, STATE_SEND_LF_WAIT
} state_type;
state_type state, n_state;
logic [3:0] x_count, n_x_count;
logic [3:0] y_count, n_y_count;
logic [31:0] wait_counter, n_wait_counter;
logic [0:0] n_we;
logic [13:0] n_a;
logic [7:0] n_data_in;
always_comb begin
n_state = state;
n_x_count = x_count;
n_y_count = y_count;
n_wait_counter = wait_counter;
n_we = WE;
n_a = A;
n_data_in = DATA_IN;
case(state)
STATE_IDLE: begin
n_state = STATE_WAIT;
end
STATE_SEND: begin
n_state = STATE_SEND_WAIT;
n_we = 1'b1;
n_data_in = Q == 0 ? 8'h20 : Q; // replace NULL to ' '
n_a = (A == 8*8-1) ? 0 : A + 1;
end
STATE_SEND_WAIT: begin
n_we = 1'b0;
if(WE == 0 && BUSY == 0) begin
n_state = (x_count == 7) ? STATE_SEND_CR : STATE_SEND;
n_x_count = (x_count == 7) ? 0 : x_count + 1;
end
end
STATE_SEND_CR: begin
n_state = STATE_SEND_CR_WAIT;
n_we = 1'b1;
n_data_in = 8'h0d; // CR
end
STATE_SEND_CR_WAIT: begin
n_we = 1'b0;
if(WE == 0 && BUSY == 0) begin
n_state = STATE_SEND_LF;
end
end
STATE_SEND_LF: begin
n_state = STATE_SEND_LF_WAIT;
n_we = 1'b1;
n_data_in = 8'h0a; // LF
end
STATE_SEND_LF_WAIT: begin
n_we = 1'b0;
if(WE == 0 && BUSY == 0) begin
n_state = (y_count == 7) ? STATE_WAIT : STATE_SEND;
n_y_count = (y_count == 7) ? 0 : y_count + 1;
end
end
STATE_WAIT: begin
if(wait_counter < 100000000) begin
n_wait_counter <= wait_counter + 1;
end else begin
n_wait_counter <= 0;
n_state <= STATE_SEND;
end
end
endcase // case (state)
end
always_ff @ (posedge CLK) begin
if (RST) begin
state <= STATE_IDLE;
x_count <= 0;
y_count <= 0;
WE <= 0;
A <= 0;
wait_counter <= 0;
end else begin
state <= n_state;
x_count <= n_x_count;
y_count <= n_y_count;
wait_counter <= n_wait_counter;
WE <= n_we;
A <= n_a;
DATA_IN <= n_data_in;
end
end // always_ff @ (posedge CLK)
endmodule // bram_to_uart
`default_nettype wire
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment