A Color Vision System for Embedded Robotics Applications

Click here to return to article

Verilog FPGA RAM Scheduler:

module ram_scheduler(
			input wire sys_clock,
			input wire force_reset,

			input wire [14:0] proc_data_w,
			input wire qual2_data,
			input wire [17:1] proc_addr,

			input wire [17:0] disp_data_get_addr,
			input wire disp_data_get_strb,			
			output reg [14:0] disp_data,

			input wire [17:0] video1_addr,
			input wire [14:0] video1_data,
			input wire video1_store_strb,

			input wire disp_ping_pong,

			output reg ram_we,
			output reg ram_oe,
			output reg ram_ce,
			output reg [19:1] ram_addr,
			inout wire [14:0] ram_data_io,
			
			output reg fifo_error,
			input wire clear_fifo_error
			);

reg [7:0] store_state_var;

reg clear_display_read_pending;
reg display_read_pending;
reg ram_data_mux1;
reg ram_data_mux2;

wire [14:0] proc_fifo_dout;
wire [17:0] proc_fifo_aout;
reg p_write_fifo_re;
wire proc_write_fifo_epty;

wire [14:0] video1_fifo_dout;
wire [17:0] video1_fifo_aout;
reg video1_fifo_re;
wire video1_write_fifo_epty;

wire f1_full;

parameter[7:0]
			DISPATCH_STATE		= 8'b00000001,
			STORE_PROC1_STATE	= 8'b00000010,
			STORE_PROC2_STATE	= 8'b00000100,
			GET_DISP1_STATE	= 8'b00001000,
			GET_DISP2_STATE	= 8'b00010000,
			STORE_VID1_STATE1	= 8'b00100000,
			STORE_VID1_STATE2	= 8'b01000000,
			STORE_VID1_STATE3	= 8'b10000000;

parameter[7:0]
			DISPATCH_CASE		= 8'bxxxxxxx1,
			STORE_PROC1_CASE	= 8'bxxxxxx1x,
			STORE_PROC2_CASE	= 8'bxxxxx1xx,
			GET_DISP1_CASE		= 8'bxxxX1xxx,
			GET_DISP2_CASE		= 8'bxxx1xxxx,
			STORE_VID1_CASE1	= 8'bxx1xxxxx,
			STORE_VID1_CASE2  = 8'bx1xxxxxx,
			STORE_VID1_CASE3  = 8'b1xxxxxxx;

always @(posedge sys_clock or posedge force_reset) begin : store_state_fsm
	if (force_reset)
		store_state_var[7:0] <= #1 DISPATCH_STATE;
	else begin
		casex (store_state_var[7:0]) // synopsys parallel_case full_case

			DISPATCH_CASE:
			begin
				if(display_read_pending)
					store_state_var[7:0] <= #1 GET_DISP1_STATE;		//always service display fetch first.
				else if(~video1_write_fifo_epty)
					store_state_var[7:0] <= #1 STORE_VID1_STATE1;
				else if(~proc_write_fifo_epty)
					store_state_var[7:0] <= #1 STORE_PROC1_STATE;
				else
					store_state_var[7:0] <= #1 DISPATCH_STATE;
			end
			
			STORE_PROC1_CASE:
			begin
				store_state_var[7:0] <= #1 STORE_PROC2_STATE;
			end

			STORE_PROC2_CASE:
			begin
				store_state_var[7:0] <= #1 DISPATCH_STATE;
			end

			GET_DISP1_CASE:
			begin
				disp_data[14:0] <= #1 ram_data_io[14:0];
				store_state_var[7:0] <= #1 GET_DISP2_STATE;
			end

			GET_DISP2_CASE:
			begin
				disp_data[14:0] <= #1 ram_data_io[14:0];
				store_state_var[7:0] <= #1 DISPATCH_STATE;
			end

			STORE_VID1_CASE1:
			begin
				store_state_var[7:0] <= #1 STORE_VID1_STATE2;
			end

			STORE_VID1_CASE2:
			begin
				store_state_var[7:0] <= #1 STORE_VID1_STATE3;
			end

			STORE_VID1_CASE3:
			begin
				store_state_var[7:0] <= #1 DISPATCH_STATE;
			end
		endcase
	end
end // store_state_fsm

always @(store_state_var[7:0],disp_ping_pong,proc_fifo_aout[17:0],disp_data_get_addr[17:0],video1_fifo_aout[17:0])begin : store2_state_assn_fsm
	casex (store_state_var[7:0]) // synopsys parallel_case full_case
		DISPATCH_CASE:
		begin
			clear_display_read_pending = 0;
			ram_we = 1;
			ram_ce = 0;
			ram_oe = 0;
			ram_data_mux1 = 0;  // high impedance
			ram_data_mux2 = 0;
			ram_addr[19:1] = {~disp_ping_pong,disp_data_get_addr[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 0;
		end
		
		STORE_PROC1_CASE:
		begin
			clear_display_read_pending = 0;
			ram_we = 0;
			ram_ce = 1;
			ram_oe = 1;
			ram_data_mux1 = 1;
			ram_data_mux2 = 0;
			ram_addr[19:1] = {disp_ping_pong,proc_fifo_aout[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 0;
		end

		STORE_PROC2_CASE:
		begin
			clear_display_read_pending = 0;
			ram_we = 0;
			ram_ce = 0;
			ram_oe = 1;
			ram_data_mux1 = 1;
			ram_data_mux2 = 0;
			ram_addr[19:1] = {disp_ping_pong,proc_fifo_aout[17:0]};
			p_write_fifo_re = 1;
			video1_fifo_re = 0;
		end

		GET_DISP1_CASE:
		begin
			clear_display_read_pending = 0;
			ram_we = 1;
			ram_ce = 0;
			ram_oe = 0;
			ram_data_mux1 = 0;
			ram_data_mux2 = 0;
			ram_addr[19:1] = {~disp_ping_pong,disp_data_get_addr[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 0;
		end

		GET_DISP2_CASE:
		begin
			clear_display_read_pending = 1;
			ram_we = 1;
			ram_ce = 0;
			ram_oe = 0;
			ram_data_mux1 = 0;
			ram_data_mux2 = 0;
			ram_addr[19:1] = {~disp_ping_pong,disp_data_get_addr[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 0;
		end

		STORE_VID1_CASE1:
		begin
			clear_display_read_pending = 0;
			ram_we = 0;
			ram_ce = 1;
			ram_oe = 1;
			ram_data_mux1 = 0;
			ram_data_mux2 = 1;
			ram_addr[19:1] = {disp_ping_pong,video1_fifo_aout[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 0;
		end

		STORE_VID1_CASE2:
		begin
			clear_display_read_pending = 0;
			ram_we = 0;
			ram_ce = 0;
			ram_oe = 1;
			ram_data_mux1 = 0;
			ram_data_mux2 = 1;
			ram_addr[19:1] = {disp_ping_pong,video1_fifo_aout[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 0;
		end

		STORE_VID1_CASE3:
		begin
			clear_display_read_pending = 0;
			ram_we = 1;
			ram_ce = 0;
			ram_oe = 1;
			ram_data_mux1 = 0;
			ram_data_mux2 = 1;
			ram_addr[19:1] = {disp_ping_pong,video1_fifo_aout[17:0]};
			p_write_fifo_re = 0;
			video1_fifo_re = 1;
		end
	endcase
end //store2_state_assn

always @(posedge sys_clock)
begin
	if(force_reset | clear_fifo_error)
		fifo_error <= #1 1'b0;
	else if(f1_full)
		fifo_error <= #1 1'b1;
end

fifo_33 video1_write_fifo(
			.clk(sys_clock),
			.rst(force_reset),
			.din({video1_data[14:0],video1_addr[17:0]}),	// [32:0]
			.we(video1_store_strb),
			.dout({video1_fifo_dout[14:0],video1_fifo_aout[17:0]}),	// [32:0]
			.re(video1_fifo_re),
			.full(f1_full),
			.empty(video1_write_fifo_epty)
			);

assign #1 ram_data_io[14:0] = ram_data_mux2 ? video1_fifo_dout[14:0] : 15'bZZZZZZZZZZZZZZZ;

fifo_33 proc_write_fifo(
			.clk(sys_clock),
			.rst(force_reset),
			.din({proc_data_w[14:0],1'b0,proc_addr[17:1]}),	// [32:0]
			.we(qual2_data),
			.dout({proc_fifo_dout[14:0],proc_fifo_aout[17:0]}),	// [32:0]
			.re(p_write_fifo_re),
			.full(),
			.empty(proc_write_fifo_epty)
			);

assign #1 ram_data_io[14:0] = ram_data_mux1 ? proc_fifo_dout[14:0] : 15'bZZZZZZZZZZZZZZZ;

always @(posedge sys_clock)
begin
	if(force_reset || clear_display_read_pending)
		display_read_pending <= #1 1'b0;
	else if(disp_data_get_strb)
		display_read_pending <= #1 1'b1;
end


endmodule

Click here to return to article