📄 top.v
字号:
.master_we_i(risc_aux_we),
.rs232_rxd_i(rs232_rxd),
.dat_io(dat),
.rst_o(rst),
.master_br_o(master_br),
.stb_o(stb),
.cyc_o(),
.adr_o(adr),
.we_o(we),
.rs232_txd_o(rs232_txd)
);
// RAM decodes
// In this project, the address bus (adr) is 16 bits wide. This provides
// enough address range to address the entire program space of the processor
// plus the entire screen memory of the LCD panel at 128 by 92 resolution.
// (There are only 12288 pixels!)
//
// The processor is able to access this address space indirectly, by setting
// up the address first within its aux_adr_lo and aux_adr_hi registers, then
// issuing reads/writes to the aux_dat location.
//
// In this way, the processor is able to load data into its own code space,
// by way of the dual port RAM... Of course, the user must be careful not
// to currupt the code which is running on the processor during this process!
// AUX Addr. Width Purpose
//----------------------------------------------------------
// 0000 - 01ff 8-bit processor code space block 0.
// 0200 - 03ff 8-bit processor code space block 1.
// 0400 - 05ff 8-bit processor code space block 2.
// 0600 - 07ff 8-bit processor code space block 3.
// 4000 - 4fff 3-bit display panel pixels block 0 (4096 pixels).
// 5000 - 5fff 3-bit display panel pixels block 1 (4096 pixels).
// 6000 - 6fff 3-bit display panel pixels block 2 (4096 pixels).
// ff00 - ffff 8-bit peripheral I/O register space
assign code_space = ((adr[15:14] == 0) && stb); // 1st 16k
assign rgb_space = ((adr[15:14] == 1) && stb); // 2nd 16k
assign ram_space = ((adr[15:9] == 7'b1000000) && stb); // 512 bytes at 8000h
assign io_space = ((adr[15:8] == 8'hff) && stb); // last 256 bytes
assign io_sel = (io_space)?(1 << adr[4:3]):0;
assign r0_wire = {sys_clk_1,switch}; // Holds possibly unused inputs
reg_8_pack #(
5, // Size of r0
1, // Size of r1
8, // Size of r2
5, // Size of r3
8, // Size of r4
6, // Size of r5
2, // Size of r6
8, // Size of r7
1, // Read only regs.
8 // Size of the data bus.
)
reg_8_pack_1 // Instance name
(
.clk_i(sys_clk_variable_half),
.rst_i(reset),
.sel_i(io_sel[0]),
.we_i(we),
.adr_i(adr[2:0]), // byte addressed...
.dat_io(dat),
.r0(r0_wire),
.r1(),
.r2(break_prog_adr[7:0]),
.r3(break_prog_adr[12:8]),
.r4(break_prog_dat[7:0]),
.r5(break_prog_dat[13:8]),
.r6(break_enable),
.r7(led)
);
reg_8_pack #(
8, // Size of r0
6, // Size of r1
1, // Size of r2
1, // Size of r3
1, // Size of r4
1, // Size of r5
1, // Size of r6
1, // Size of r7
2, // Read only regs.
8 // Size of the data bus.
)
reg_8_pack_2 // Instance name
(
.clk_i(sys_clk_variable_half),
.rst_i(reset),
.sel_i(io_sel[2]),
.we_i(we),
.adr_i(adr[2:0]), // byte addressed...
.dat_io(dat),
.r0(port_f[7:0]),
.r1(port_f[13:8]),
.r2(),
.r3(),
.r4(),
.r5(),
.r6(),
.r7()
);
// The following register set and logic is to control single stepping the
// processor. Actually, stepping in groups of 2, 3, 4 or more is permitted.
// Also, a breakpoint will reset the stepping counter.
// If running free, a breakpoint will reset the "run_free" and "forced_reset"
// bits.
reg_4_pack_clrset #(
1, // Size of r0
1, // Size of r1
6, // Size of r2
2, // Size of r3
0, // Read only regs.
8 // Size of the data bus.
)
reg_4_pack_clrset_1 // Instance name
(
.clk_i(sys_clk_variable_half),
.rst_i(reset),
.sel_i(io_sel[1]),
.we_i(we),
.adr_i(adr[1:0]), // byte addressed... byte accessible only
.clr_i({2'b0,begin_stepping,breakpoint}),
.set_i(4'b0),
.dat_io(dat),
.r0(),
.r1(begin_stepping),
.r2(clocks_to_step),
.r3(processor_control)
);
assign run_free = processor_control[1]; // Not free running at power up
assign forced_reset = processor_control[0];
// This part generates the bus_rdy signal for the processor.
// This is how single stepping is implemented. Actually, execution in
// steps of 2,3 or more instructions at a time is also allowed.
assign reset_single_stepper = reset || breakpoint;
always @(posedge sys_clk_variable_half or posedge reset_single_stepper)
begin
if (reset_single_stepper) step_count <= 0; // Asynchronous reset
else
begin // Clock edge
if (begin_stepping) step_count <= clocks_to_step;
else if (stepping_active) step_count <= step_count - 1;
end
end
assign stepping_active = (step_count > 0);
assign bus_rdy = (stepping_active || run_free) && (~breakpoint);
assign breakpoint = (
(break_enable[0] && (break_prog_adr == risc_prog_adr))
|| (break_enable[1] && (break_prog_dat == risc_prog_dat[13:0]))
);
//---------------------------------------------------------------------
// 2048 bytes of program RAM (2048 x 8 on A, 1024 x 16 on B)
assign dat = (code_space && ~we)?code_ram_dat_o:{8{1'bZ}};
ramb16_s8_s16
code_space_ram
(
.dat_o_s8a(code_ram_dat_o),
.dat_i_s8a(dat),
.adr_i_s8a(adr[10:0]),
.clk_i_s8a(sys_clk_variable),
.rst_i_s8a(reset),
.we_i_s8a(we & code_space),
.dat_o_s16b(risc_prog_dat),
.dat_i_s16b(16'b0), // Processor only reads instruction words...
.adr_i_s16b(risc_prog_adr[9:0]),
.clk_i_s16b(sys_clk_variable),
.rst_i_s16b(reset),
.we_i_s16b(1'b0) // Processor only reads instruction words...
);
// 12k of 3-bit RAM (12288 x 3)
// Each location corresponds to one pixel on a display of 128x96 pixels.
// Each data word [2:0] is blue,green,red.
assign dat[2:0] = (rgb_space && ~we)?rgb_ram_dat_o:{3{1'bZ}};
ramb12_s3_s3
rgb_space_ram
(
.dat_o_s3a(rgb_ram_dat_o),
.dat_i_s3a(dat[2:0]),
.adr_i_s3a(adr[13:0]),
.clk_i_s3a(sys_clk_variable),
.rst_i_s3a(reset),
.we_i_s3a(we & rgb_space),
.dat_o_s3b(pixel_dat),
.dat_i_s3b(3'b000), // Display only reads pixel data...
.adr_i_s3b(pixel_adr),
.clk_i_s3b(sys_clk_lcd),
.rst_i_s3b(reset),
.we_i_s3b(1'b0) // Display only reads pixel data...
);
// 512 bytes of register file RAM for the risc16f84 processor.
// These are memory mapped into the AUX bus on the A port of the RAM,
// to facilitate debugging (One can examine the contents of registers from
// the rs232_syscon command prompt!)
assign dat = (ram_space && ~we)?regfile_ram_dat_o:{8{1'bZ}};
RAMB4_S8_S8
risc16f84_regs
(
.DOA(regfile_ram_dat_o),
.DIA(dat),
.ADDRA(adr[8:0]),
.CLKA(sys_clk_variable),
.ENA(ram_space),
.RSTA(reset),
.WEA(we),
.DOB(risc_ram_dat_i),
.DIB(risc_ram_dat_o),
.ADDRB(risc_ram_adr),
.CLKB(sys_clk_variable),
.ENB(1'b1),
.RSTB(reset),
.WEB(risc_ram_we)
);
//--------------------------------------------------------------------------
// Module code
//--------------------------------------------------------------------------
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -