Source

pv200_avrcore / de2test.v

module de2test(
	input CLOCK_27,

	input[3:0] KEY,
	output[6:0] HEX0,
	output[6:0] HEX1,
	output[6:0] HEX2,
	output[6:0] HEX3,
	output[6:0] HEX4,
	output[6:0] HEX5,
	output[6:0] HEX6,
	output[6:0] HEX7,

	output reg[7:0] LCD_DATA,
	output LCD_EN,
	output reg LCD_RS,
	output LCD_RW,
	output LCD_ON,

	output UART_TXD,
	input UART_RXD,

	output reg[7:0] LEDG,
	output[15:0] LEDR
);

wire rst = !KEY[0];

wire clk;
clock_div main_clock_div(
	.RST(rst),
	.CLKIN(CLOCK_27),
	.CLKOUT(clk)
);
//defparam main_clock_div.width = 32;
//defparam main_clock_div.top = 2_000_000;
defparam main_clock_div.top = 1;

wire[15:0] ram_addr;
reg[7:0] ram_data_in;
wire[7:0] ram_data_out;

wire[15:0] prog_addr;
wire[15:0] rom_value;
wire ram_rd;
wire ram_wr;
avrcorev avrcore0(
	.reset(rst),
	.clock(clk),
	.clken(1'b1),
	.prog_data(rom_value),
	.prog_addr(prog_addr),
	.ram_data_in(ram_data_in),
	.ram_data_out(ram_data_out),
	.ram_addr(ram_addr),
	.ram_rd(ram_rd),
	.ram_wr(ram_wr),
	.debug(LEDR[15:0])
);

prog_mem prog_mem0(
	.address(prog_addr[10:0]),
	.clken(1'b1),
	.clock(clk),
	.q(rom_value)
);

wire[7:0] data_ram0_out;
data_ram data_ram0(
	.address(ram_addr - 9'h100),
	.clken(1'b1),
	.clock(!clk),
	.data(ram_data_out),
	.wren(ram_addr >= 9'h100 && ram_wr),
	.q(data_ram0_out)
);

assign LCD_ON = 1'b1;
assign LCD_RW = 1'b0;
reg lcd_start_wr;
wire lcd_busy;
lcd_cycle lcd(
	.RST(rst),
	.CLK(clk),
	.CLKEN(1'b1),
	.WR(lcd_start_wr),
	.BUSY(lcd_busy),
	.OUTEN(LCD_EN),
	.RS(LCD_RS)
);

reg[7:0] uart_tx_data;
reg uart_tx_start;
wire uart_tx_busy;
uart_transmitter uart0_tx(
	.RST(rst),
	.CLK(clk),
	.CLKEN(1'b1),
	.DATA(uart_tx_data),
	.START(uart_tx_start),
	.TX(UART_TXD),
	.BUSY(uart_tx_busy)
);

wire[7:0] uart_rx_data;
wire uart_rx_done;
uart_receiver usart0_rx(
	.RST(rst),
	.CLK(clk),
	.CLKEN(1'b1),
	.RX(UART_RXD),
	.DATA(uart_rx_data),
	.RXDONE(uart_rx_done),
);

reg uart_rx_fetched;
reg uart_rx_data_buf_full;
reg[7:0] uart_rx_data_buf;

always @(posedge clk) begin
	lcd_start_wr <= 1'b0;
	if (uart_tx_busy)
		uart_tx_start <= 1'b0;

	if (uart_rx_done && !uart_rx_fetched && !uart_rx_data_buf_full) begin
		uart_rx_fetched <= 1'b1;
		uart_rx_data_buf_full <= 1'b1;
		uart_rx_data_buf <= uart_rx_data;
	end
	
	if (!uart_rx_done)
		uart_rx_fetched <= 1'b0;

	if (ram_rd) begin
		case (ram_addr)
		16'hfb: begin // UART_DATA
			uart_rx_data_buf_full <= 1'b0;
		end
		endcase
	end
	
	if (ram_wr) begin
		case (ram_addr)
		16'hfb: begin // UART_DATA
			uart_tx_data <= ram_data_out;
			uart_tx_start <= 1'b1;
		end
		16'hfd: begin // LEDG
			LEDG <= ram_data_out;
		end
		16'hfe: begin // LDC_CTRL
			LCD_RS <= ram_data_out[7];
		end
		16'hff: begin // LDC_DATA
			LCD_DATA <= ram_data_out;
			lcd_start_wr <= 1'b1;
		end
		endcase
	end
end

always @* begin
	ram_data_in = 8'hxx;
	if (ram_rd) begin
		case (ram_addr)
		16'hfa: begin // UART_CTRL
			ram_data_in = { 6'bx, uart_rx_data_buf_full, !(uart_tx_busy || uart_tx_start) };
		end
		16'hfb: begin // UART_DATA
			ram_data_in = uart_rx_data_buf;
		end
		16'hfc: begin // KEY
			ram_data_in = KEY;
		end
		16'hfd: begin // LEDG
			ram_data_in = LEDG;
		end
		16'hfe: begin // LDC_CTRL
			ram_data_in = lcd_start_wr || lcd_busy;
		end
		default:
			if (ram_addr >= 9'h100)
				ram_data_in = data_ram0_out;
		endcase
	end
end

wire[31:0] hex_value = { ram_addr[7:0], ram_rd? ram_data_in[7:0]: ram_wr? ram_data_out[7:0]: {prog_addr[6:0], 1'b0}, rom_value };

sevenseg hexdriver0(
	.IN(hex_value[3:0]),
	.OUT(HEX0)
);

sevenseg hexdriver1(
	.IN(hex_value[7:4]),
	.OUT(HEX1)
);

sevenseg hexdriver2(
	.IN(hex_value[11:8]),
	.OUT(HEX2)
);

sevenseg hexdriver3(
	.IN(hex_value[15:12]),
	.OUT(HEX3)
);

sevenseg hexdriver4(
	.IN(hex_value[19:16]),
	.OUT(HEX4)
);

sevenseg hexdriver5(
	.IN(hex_value[23:20]),
	.OUT(HEX5)
);

sevenseg hexdriver6(
	.IN(hex_value[27:24]),
	.OUT(HEX6)
);

sevenseg hexdriver7(
	.IN(hex_value[31:28]),
	.OUT(HEX7)
);

endmodule