リスト4 ロジック回路として実装するネガポジ反転処理(image_convert.v)
module image_convert
(
input SYSCLK,
input CLK,
input RESET,
//--Write Bus Interface
output reg m_axi_awvalid,
input m_axi_awready,
output reg [ 31:0] m_axi_awaddr,
output reg [ 7:0] m_axi_awlen,
output reg [ 2:0] m_axi_awsize,
output reg [ 1:0] m_axi_awburst,
output reg m_axi_awlock,
output reg [ 3:0] m_axi_awcache,
output reg [ 2:0] m_axi_awprot,
output reg m_axi_wvalid,
input m_axi_wready,
output reg [127:0] m_axi_wdata,
output reg [ 15:0] m_axi_wstrb,
output reg m_axi_wlast,
input m_axi_bvalid,
output reg m_axi_bready,
input [ 1:0] m_axi_bresp,
//--Read Bus Interface
output reg m_axi_arvalid,
output reg [ 31:0] m_axi_araddr,
output reg [ 7:0] m_axi_arlen,
output reg [ 2:0] m_axi_arsize,
output reg [ 1:0] m_axi_arburst,
output reg [ 2:0] m_axi_arprot,
output reg [ 1:0] m_axi_arlock,
output reg [ 3:0] m_axi_arcache,
input m_axi_arready,
input m_axi_rvalid,
output reg m_axi_rready,
input [127:0] m_axi_rdata,
input [ 1:0] m_axi_rresp,
input m_axi_rlast,
input cmd_valid,
output cmd_ready,
input [ 9:0] cmd_function_id,
input [ 31:0] cmd_inputs_0,
input [ 31:0] cmd_inputs_1,
output reg rsp_valid,
input rsp_ready,
output [ 31:0] rsp_outputs_0
);
reg [3:0] state;
localparam STATE_IDLE = 4'h0;
localparam STATE_READ_REQ = 4'h1;
localparam STATE_READ_ACK = 4'h2;
localparam STATE_READ_VALID = 4'h3;
localparam STATE_WRITE_REQ = 4'h4;
localparam STATE_WRITE_ACK = 4'h5;
localparam STATE_WRITE_VALID = 4'h6;
localparam STATE_WRITE_DONE = 4'h7;
localparam STATE_NEXT = 4'h8;
localparam STATE_RESP = 4'h9;
localparam FRAME_LOOPCNT = 507;
localparam CYCLE_BURST_LAST = 8'h3F;
localparam CYCLE_BURST = 8'hFF;
wire w_readreq_ack;
wire w_writereq_ack;
wire w_readburst_done;
wire w_writeburst_done;
wire w_loop_done;
wire w_mem_we;
wire [15:0] w_burstnum;
reg [ 15:0] r_loopcnt;
reg [ 15:0] r_readcnt;
reg [ 15:0] r_writecnt;
reg [ 3:0] r_wready_shift;
reg [127:0] r_wdata_shift [3:0];
reg [127:0] r_mem_rd;
reg [ 2:0] r_transfer_start;
reg r_state_is_resp;
reg [ 2:0] r_state_done;
reg [127:0] mem [255:0];
reg [ 31:0] reg_src_addr;
reg [ 31:0] reg_dest_addr;
reg [ 3:0] reg_start;
reg [ 2:0] reg_resp;
reg reg_resp_done;
assign cmd_ready = (state == STATE_IDLE) ?
1'b1 : 1'b0;
always@(posedge SYSCLK)
begin
if (RESET) begin
reg_src_addr <= 0;
reg_dest_addr <= 0;
reg_start <= 0;
end else begin
if (cmd_ready & cmd_valid) begin
case (cmd_function_id[9:0])
10'd0: begin
reg_src_addr <= cmd_inputs_0;
reg_dest_addr <= cmd_inputs_1;
reg_start <= 4'hF;
end
default: begin
reg_src_addr <= reg_src_addr;
reg_dest_addr <= reg_dest_addr;
reg_start <= {reg_start[2:0], 1'b0};
end
endcase
end
else begin
reg_start <= {reg_start[2:0], 1'b0};
end
end
end
always@(posedge SYSCLK)
begin
if (RESET) begin
reg_resp <= 0;
end else begin
reg_resp <= {reg_resp[1:0], r_state_is_resp};
end
end
always@(posedge SYSCLK)
begin
if (RESET) begin
reg_resp_done <= 0;
end else begin
if (!reg_resp[2]) reg_resp_done <= 1'b0;
else if (rsp_valid && rsp_ready) reg_resp_done <= 1'b1;
end
end
always@(posedge SYSCLK)
begin
if (RESET) begin
rsp_valid <= 0;
end else begin
if (!reg_resp_done && reg_resp[2] &&
rsp_ready && !rsp_valid)
rsp_valid <= 1'b1;
else
rsp_valid <= 1'b0;
end
end
assign w_readburst_done =
(m_axi_rvalid & m_axi_rlast);
assign w_writeburst_done =
(m_axi_wlast & m_axi_wvalid);
assign w_loop_done =
(r_loopcnt >= FRAME_LOOPCNT) ? 1'b1 : 1'b0;
assign w_burstnum = (r_loopcnt == FRAME_
LOOPCNT-1) ? CYCLE_BURST_LAST : CYCLE_BURST;
always@(posedge CLK)
begin
if (RESET) begin
r_transfer_start <= 0;
end
else begin
r_transfer_start <= {r_transfer_start[1:0], reg_start[3]};
end
end
always@(posedge CLK)
begin
if (RESET) begin
state <= STATE_IDLE;
end
else begin
case (state)
STATE_IDLE:
if (r_transfer_start[2]) state <=
STATE_READ_REQ;
STATE_READ_REQ:
state <= STATE_READ_ACK;
STATE_READ_ACK:
if (m_axi_arready && m_axi_arvalid)
state <= STATE_READ_VALID;
STATE_READ_VALID:
if (w_readburst_done) state <=
STATE_WRITE_REQ;
STATE_WRITE_REQ:
state <= STATE_WRITE_ACK;
STATE_WRITE_ACK:
if (m_axi_awready && m_axi_awvalid)
state <= STATE_WRITE_VALID;
STATE_WRITE_VALID:
if (w_writeburst_done) state <=
STATE_WRITE_DONE;
STATE_WRITE_DONE:
if (m_axi_bvalid) state <= STATE_NEXT;
STATE_NEXT:
if (w_loop_done) state <= STATE_RESP;
else state <= STATE_READ_REQ;
STATE_RESP:
if (r_state_done[2]) state <=
STATE_IDLE;
default:
state <= STATE_IDLE;
endcase
end
end
always@(posedge CLK)
begin
if (state == STATE_RESP)
r_state_is_resp <= 1'b1;
else
r_state_is_resp <= 1'b0;
end
always@(posedge CLK)
begin
r_state_done <= {r_state_done[1:0], reg_resp_done};
end
always@(posedge CLK)
begin
if (RESET || state==STATE_IDLE) begin
m_axi_awvalid <= 0; m_axi_awaddr <= 0;
m_axi_awlen <= 0; m_axi_awsize <= 0;
m_axi_awburst <= 0; m_axi_awlock <= 0;
m_axi_awcache <= 0; m_axi_awprot <= 0;
m_axi_wvalid <= 0; m_axi_wdata <= 0;
m_axi_wstrb <= 0; m_axi_wlast <= 0;
m_axi_bready <= 0; m_axi_arvalid <= 0;
m_axi_araddr <= 0; m_axi_arlen <= 0;
m_axi_arsize <= 0; m_axi_arburst <= 0;
m_axi_arprot <= 0; m_axi_arlock <= 0;
m_axi_arcache <= 0; m_axi_rready <= 0;
end
else begin
case (state)
STATE_IDLE: begin
m_axi_awvalid <= 0; m_axi_awaddr <= 0;
m_axi_awlen <= 0; m_axi_awsize <= 0;
m_axi_awburst <= 0; m_axi_awlock <= 0;
m_axi_awcache <= 0; m_axi_awprot <= 0;
m_axi_wvalid <= 0; m_axi_wdata <= 0;
m_axi_wstrb <= 0; m_axi_wlast <= 0;
m_axi_bready <= 0; m_axi_arvalid <= 0;
m_axi_araddr <= 0; m_axi_arlen <= 0;
m_axi_arsize <= 0; m_axi_arburst <= 0;
m_axi_arprot <= 0; m_axi_arlock <= 0;
m_axi_arcache <= 0; m_axi_rready <= 0;
end
STATE_READ_REQ: begin
m_axi_araddr <= reg_src_addr +
{r_loopcnt, 12'd0};
m_axi_arlen <= w_burstnum;
m_axi_arsize <= 3'b010;
m_axi_arburst <= 2'b01;
m_axi_arvalid <= 1'b1;
m_axi_rready <= 1'b1;
end
STATE_READ_ACK:
if (m_axi_arready && m_axi_arvalid)
m_axi_arvalid <= 1'b0;
STATE_READ_VALID:
if (m_axi_rvalid) begin
if (m_axi_rlast)
m_axi_rready <= 1'b0;
else
m_axi_rready <= 1'b1;
end
STATE_WRITE_REQ: begin
m_axi_awaddr <= reg_dest_addr +
{r_loopcnt, 12'd0};
m_axi_awlen <= w_burstnum;
m_axi_awsize <= 3'b010;
m_axi_awburst <= 2'b01;
m_axi_awvalid <= 1'b1;
end
STATE_WRITE_ACK:
if (m_axi_awready && m_axi_awvalid)
m_axi_awvalid <= 1'b0;
STATE_WRITE_VALID: begin
if (m_axi_wlast && m_axi_wready &&
m_axi_wvalid) begin
m_axi_wvalid <= 1'b0;
m_axi_wlast <= 1'b0;
m_axi_bready <= 1'b1;
end
else begin
if (r_wready_shift[2]) begin
m_axi_wvalid <= 1'b1;
m_axi_wstrb <= 16'hFFFF;
end
if (r_writecnt==w_burstnum+4-1)
begin
m_axi_wlast <= 1'b1;
end
end
//ネガポジ反転して書き戻す
m_axi_wdata <= ~r_wdata_shift[1];
end
STATE_WRITE_DONE:
if (m_axi_bvalid) m_axi_bready <=
1'b0;
default: begin
m_axi_arvalid <= 0;
m_axi_awvalid <= 0;
end
endcase
end
end
always@(posedge CLK)
begin
if (RESET || state==STATE_IDLE) begin
r_loopcnt <= 0;
end
else begin
if (w_writeburst_done) begin
r_loopcnt <= r_loopcnt + 1;
end
end
end
always@(posedge CLK)
begin
if (RESET || state==STATE_READ_REQ) begin
r_readcnt <= 0;
end
else begin
if (m_axi_rvalid & m_axi_rready) begin
r_readcnt <= r_readcnt + 1;
end
end
end
always@(posedge CLK)
begin
if (RESET || state==STATE_IDLE) begin
r_wready_shift <= 0;
end
else begin
if (state==STATE_WRITE_VALID && m_axi_wready) begin
r_wready_shift[0] <= 1'b1;
end
else begin
r_wready_shift[0] <= 1'b0;
end
r_wready_shift[3:1] <= r_wready_shift[2:0];
if (state==STATE_WRITE_VALID &&
m_axi_wready) begin
r_wdata_shift[3] <= r_wdata_shift[2];
r_wdata_shift[2] <= r_wdata_shift[1];
r_wdata_shift[1] <= r_wdata_shift[0];
r_wdata_shift[0] <= r_mem_rd;
end
end
end
always@(posedge CLK)
begin
if (RESET || state == STATE_IDLE || state ==
STATE_WRITE_DONE ) begin
r_writecnt <= 0;
end
else begin
if (state==STATE_WRITE_VALID) begin
r_writecnt <= r_writecnt + 1;
end
end
end
assign w_mem_we = m_axi_rvalid;
always@(posedge CLK)
begin
if (w_mem_we) mem[r_readcnt[7:0]] <= m_axi_rdata;
end
always@(posedge CLK)
begin
r_mem_rd <= mem[r_writecnt[7:0]];
end
endmodule