リスト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

コメントを残す