/* * Portions of this file copyright David Carne. * Portions of this file copyright Xilinx INC. * Derived from the uClock example * */ module top ( // 50mhz clock clk, // inputs + outputs tx, rx, // Ram bus CE1,CE2,UB1,UB2,LB1,LB2,OE,WE,ADDR,DATA, // Camera inputs fvalid, lvalid, vclk, pix_data ); output tx; input rx; input clk; output [17:0] ADDR; inout [31:0] DATA; output CE1,CE2,UB1,UB2,LB1,LB2,OE,WE; wire tx; wire rx; wire clk; input vclk; input fvalid; input lvalid; input [7:0] pix_data; // Rename lvalid + fvalid assign hsync = lvalid; assign vsync = fvalid; // we set ram_multiplex to select between both blocks localparam RAM_CPU = 0; localparam RAM_CAP = 1; wire ram_multiplex; /* Regs the CPU needs for reading + writing */ reg [31:0] ram_cpu_data_write; wire [31:0] ram_cpu_data_read; reg [17:0] ram_cpu_addr; wire ram_cpu_write; /* Regs the Capture Block needs for writing */ wire [31:0] ram_cap_data_write; wire [11:0] line_length; // Length of a single line in the frame. Value is in bytes [usually 1280] wire [9:0] line_count; // Number of lines in a single frame. [usually 480] reg capture_trigger; // Set capture trigger - leave set until done wire capture_done; // Capture done is asserted at the end of a frame capture wire cap_wants_mem; // asserted when the capture block needs a lock on the memory wire [17:0] ram_cap_addr; wire ram_cap_write; // Multiplexer to select between capture + cpu wire [31:0] ram_gen_data_write = (ram_multiplex == RAM_CPU) ? ram_cpu_data_write : ram_cap_data_write; wire [17:0] ram_gen_addr = (ram_multiplex == RAM_CPU) ? ram_cpu_addr : ram_cap_addr; wire ram_gen_write = (ram_multiplex == RAM_CPU) ? ram_cpu_write : ram_cap_write; assign DATA = ram_gen_write ? ram_gen_data_write : {32{1'bZ}}; assign ADDR = ram_gen_addr; assign ram_cpu_data_read = (ram_multiplex == RAM_CPU) ? DATA : 0; assign ram_multiplex = (cap_wants_mem) ? RAM_CAP : RAM_CPU; // OE when we're not writing [ACTIVE LOW] assign OE = ram_gen_write; // WE when we are writing [ACTIVE LOW] assign WE = !ram_gen_write; // We want to write to both chips, all bytes assign UB1 = 0; assign UB2 = 0; assign LB1 = 0; assign LB2 = 0; assign CE1 = 0; assign CE2 = 0; /* * Instantion of the capture / triggering block * * */ capture_block cam_capt( .clk(clk), .capture_trigger(capture_trigger), .capture_done(capture_done), .mem_take(cap_wants_mem), .mem_write_strobe(ram_cap_write), .mem_data(ram_cap_data_write), .mem_addr(ram_cap_addr), .vclk(!vclk), .hsync(hsync), .vsync(vsync), .pixel_data(pix_data), .hsync_line_length(line_length), .hsync_count(line_count) ); /* * Frequency counter * * */ wire [31:0] frequency_out; // Frequency in counts / second freq_count frequency_counter ( .clk_50m(clk), .samp_clk(vclk), .freq(frequency_out) ); /* * Code after this point is either copyright XILINX or derived from code copyright Xilinx. * I am of the opinion that posting this code is legally ok - as similar porions can be * * * */ wire [9:0] address; wire [17:0] instruction; wire [7:0] port_id; wire [7:0] out_port; reg [7:0] in_port; wire write_strobe; wire read_strobe; // Signals for connection of peripherals wire [7:0] status_port; // Signals for UART connections reg [9:0] baud_count; reg en_16_x_baud; wire write_to_uart; wire tx_full; wire tx_half_full; reg read_from_uart; wire [7:0] rx_data; wire rx_data_present; wire rx_full; wire rx_half_full; wire reset; //-------------------------------------------------------------------------------------------------------------------------------- // KCPSM3 and the program memory //-------------------------------------------------------------------------------------------------------------------------------- // kcpsm3 processor ( .address(address), .instruction(instruction), .port_id(port_id), .write_strobe(write_strobe), .out_port(out_port), .read_strobe(read_strobe), .in_port(in_port), .interrupt(1'b0), .reset(reset), .clk(clk)); cam_code program_rom ( .address(address), .instruction(instruction), .clk(clk), .proc_reset(reset) ); //-------------------------------------------------------------------------------------------------------------------------------- // KCPSM3 input ports //-------------------------------------------------------------------------------------------------------------------------------- // // // Status signals to form a bus // assign status_port = {2'b00, capture_done,rx_data_present,rx_full,rx_half_full,tx_full,tx_half_full}; // // The inputs connect via a pipelined multiplexer // always @(posedge clk) begin case(port_id ) // read status at address 00 hex 8'b 0 : begin in_port <= status_port; end // read UART receive data at address 01 hex 8'b 1 : begin in_port <= rx_data; end // Address 30-33: Ram data, LSB first 8'h30: begin in_port <= ram_cpu_data_read[7:0]; end 8'h31: begin in_port <= ram_cpu_data_read[15:8]; end 8'h32: begin in_port <= ram_cpu_data_read[23:16]; end 8'h33: begin in_port <= ram_cpu_data_read[31:24]; end // Addresses 40-42: Ram ADDR, LSB first 8'h40: begin in_port <= ram_cpu_addr[7:0]; end 8'h41: begin in_port <= ram_cpu_addr[15:8]; end 8'h42: begin in_port <= ram_cpu_addr[17:16]; end // 8'h60: begin in_port <= frequency_out[7:0]; end 8'h61: begin in_port <= frequency_out[15:8]; end 8'h62: begin in_port <= frequency_out[23:16]; end 8'h63: begin in_port <= frequency_out[31:24]; end 8'h70: begin in_port <= line_length[7:0]; end 8'h71: begin in_port <= line_length[11:8]; end 8'h72: begin in_port <= line_count[7:0]; end 8'h73: begin in_port <= line_count[9:8]; end // Don't care used for all other addresses to ensure minimum logic implementation default : begin in_port <= 8'b XXXXXXXX; end endcase // Form read strobe for UART receiver FIFO buffer. // The fact that the read strobe will occur after the actual data is read by // the KCPSM3 is acceptable because it is really means 'I have read you'! read_from_uart <= read_strobe & (port_id == 8'b1) ; end //-------------------------------------------------------------------------------------------------------------------------------- // KCPSM3 output ports //-------------------------------------------------------------------------------------------------------------------------------- // always @(posedge clk) begin if(write_strobe == 1'b 1) begin // Led register at address 00 hex with data bit0 providing control case (port_id) 8'h0: begin // leds <= out_port; end 8'h30: begin ram_cpu_data_write[7:0] <= out_port; end 8'h31: begin ram_cpu_data_write[15:8] <= out_port; end 8'h32: begin ram_cpu_data_write[23:16] <= out_port; end 8'h33: begin ram_cpu_data_write[31:24] <= out_port; end 8'h40: begin ram_cpu_addr[7:0] <= out_port; end 8'h41: begin ram_cpu_addr[15:8] <= out_port; end 8'h42: begin ram_cpu_addr[17:16] <= out_port[1:0]; end 8'h50: begin capture_trigger <= out_port[0]; end endcase end end // // write to UART transmitter FIFO buffer at address 01 hex. // This is a combinatorial decode because the FIFO is the 'port register'. // assign write_to_uart = write_strobe & (port_id == 8'b1); assign ram_cpu_write = write_strobe & (port_id == 8'h43); // //-------------------------------------------------------------------------------------------------------------------------------- // UART //-------------------------------------------------------------------------------------------------------------------------------- // // Connect the 8-bit, 1 stop-bit, no parity transmit and receive macros. // Each contains an embedded 16-byte FIFO buffer. // uart_tx transmit ( .data_in(out_port), .write_buffer(write_to_uart), .reset_buffer(1'b0), .en_16_x_baud(en_16_x_baud), .serial_out(tx), .buffer_full(tx_full), .buffer_half_full(tx_half_full), .clk(clk)); uart_rx receive ( .serial_in(rx), .data_out(rx_data), .read_buffer(read_from_uart), .reset_buffer(1'b0), .en_16_x_baud(en_16_x_baud), .buffer_data_present(rx_data_present), .buffer_full(rx_full), .buffer_half_full(rx_half_full), .clk(clk)); // 9600 = 324 // 230400 = 324 / 24 = 13 always @(posedge clk) begin if (baud_count == 13) begin baud_count <= 1'b0; en_16_x_baud <= 1'b1; end else begin baud_count <= baud_count + 1; en_16_x_baud <= 1'b0; end end endmodule