From cf01b391440fc9de43597b907acfc22dba1aa15e Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sun, 18 Jun 2017 14:38:03 +0200 Subject: Add j1 --- j1 | 1 - j1/verilog/xilinx-top.v | 215 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+), 1 deletion(-) delete mode 160000 j1 create mode 100644 j1/verilog/xilinx-top.v (limited to 'j1/verilog/xilinx-top.v') diff --git a/j1 b/j1 deleted file mode 160000 index 9114396..0000000 --- a/j1 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 911439641c002a8f7a6e306ce1b1d3fd4b389fd6 diff --git a/j1/verilog/xilinx-top.v b/j1/verilog/xilinx-top.v new file mode 100644 index 0000000..6695d77 --- /dev/null +++ b/j1/verilog/xilinx-top.v @@ -0,0 +1,215 @@ +`default_nettype none + + +module bram_tdp #( + parameter DATA = 72, + parameter ADDR = 10 +) ( + // Port A + input wire a_clk, + input wire a_wr, + input wire [ADDR-1:0] a_addr, + input wire [DATA-1:0] a_din, + output reg [DATA-1:0] a_dout, + + // Port B + input wire b_clk, + input wire b_wr, + input wire [ADDR-1:0] b_addr, + input wire [DATA-1:0] b_din, + output reg [DATA-1:0] b_dout +); + +// Shared memory +reg [DATA-1:0] mem [(2**ADDR)-1:0]; + initial begin + $readmemh("../build/firmware/demo0.hex", mem); + end + +// Port A +always @(posedge a_clk) begin + a_dout <= mem[a_addr]; + if(a_wr) begin + a_dout <= a_din; + mem[a_addr] <= a_din; + end +end + +// Port B +always @(posedge b_clk) begin + b_dout <= mem[b_addr]; + if(b_wr) begin + b_dout <= b_din; + mem[b_addr] <= b_din; + end +end + +endmodule + +// A 16Kbyte RAM (4096x32) with one write port and one read port +module ram16k0( + input wire clk, + + input wire[15:0] a_addr, + output wire[31:0] a_q, + input wire[31:0] a_d, + input wire a_wr, + + input wire[12:0] b_addr, + output wire[15:0] b_q); + + //synthesis attribute ram_style of mem is block + reg [31:0] mem[0:4095]; //pragma attribute mem ram_block TRUE + initial begin + $readmemh("../build/firmware/demo0.hex", mem); + end + + always @ (posedge clk) + if (a_wr) + mem[a_addr[13:2]] <= a_d; + + reg [15:0] a_addr_; + always @ (posedge clk) + a_addr_ <= a_addr; + assign a_q = mem[a_addr_[13:2]]; + + reg [12:0] raddr_reg; + always @ (posedge clk) + raddr_reg <= b_addr; + wire [31:0] insn32 = mem[raddr_reg[12:1]]; + assign b_q = raddr_reg[0] ? insn32[31:16] : insn32[15:0]; +endmodule + +module ram16k( + input wire clk, + + input wire[15:0] a_addr, + output wire[31:0] a_q, + input wire[31:0] a_d, + input wire a_wr, + + input wire[12:0] b_addr, + output wire[15:0] b_q); + + wire [31:0] insn32; + + bram_tdp #(.DATA(32), .ADDR(12)) nram ( + .a_clk(clk), + .a_wr(a_wr), + .a_addr(a_addr[13:2]), + .a_din(a_d), + .a_dout(a_q), + + .b_clk(clk), + .b_wr(1'b0), + .b_addr(b_addr[12:1]), + .b_din(32'd0), + .b_dout(insn32)); + + reg ba_; + always @(posedge clk) + ba_ <= b_addr[0]; + assign b_q = ba_ ? insn32[31:16] : insn32[15:0]; + +endmodule + + +module top( + input wire CLK, + output wire DUO_LED, + input wire DUO_SW1, + input wire RXD, + output wire TXD, + input wire DTR + ); + localparam MHZ = 40; + + wire fclk; + + DCM_CLKGEN #( + .CLKFX_MD_MAX(0.0), // Specify maximum M/D ratio for timing anlysis + .CLKFX_DIVIDE(32), // Divide value - D - (1-256) + .CLKFX_MULTIPLY(MHZ), // Multiply value - M - (2-256) + .CLKIN_PERIOD(31.25), // Input clock period specified in nS + .STARTUP_WAIT("FALSE") // Delay config DONE until DCM_CLKGEN LOCKED (TRUE/FALSE) + ) + DCM_CLKGEN_inst ( + .CLKFX(fclk), // 1-bit output: Generated clock output + .CLKIN(CLK), // 1-bit input: Input clock + .FREEZEDCM(0), // 1-bit input: Prevents frequency adjustments to input clock + .PROGCLK(0), // 1-bit input: Clock input for M/D reconfiguration + .PROGDATA(0), // 1-bit input: Serial data input for M/D reconfiguration + .PROGEN(0), // 1-bit input: Active high program enable + .RST(0) // 1-bit input: Reset input pin + ); + + reg [25:0] counter; + always @(posedge fclk) + counter <= counter + 26'd1; + assign DUO_LED = counter[25]; + + // ------------------------------------------------------------------------ + + wire uart0_valid, uart0_busy; + wire [7:0] uart0_data; + wire uart0_rd, uart0_wr; + reg [31:0] baud = 32'd115200; + wire UART0_RX; + buart #(.CLKFREQ(MHZ * 1000000)) _uart0 ( + .clk(fclk), + .resetq(1'b1), + .baud(baud), + .rx(RXD), + .tx(TXD), + .rd(uart0_rd), + .wr(uart0_wr), + .valid(uart0_valid), + .busy(uart0_busy), + .tx_data(dout_[7:0]), + .rx_data(uart0_data)); + + wire [15:0] mem_addr; + wire [31:0] mem_din; + wire mem_wr; + wire [31:0] dout; + + wire [12:0] code_addr; + wire [15:0] insn; + + wire io_wr; + + wire resetq = DTR; + + j1 _j1 ( + .clk(fclk), + .resetq(resetq), + + .io_wr(io_wr), + .mem_addr(mem_addr), + .mem_wr(mem_wr), + .mem_din(mem_din), + .dout(dout), + .io_din({16'd0, uart0_data, 4'd0, DTR, uart0_valid, uart0_busy, DUO_SW1}), + + .code_addr(code_addr), + .insn(insn) + ); + + ram16k ram(.clk(fclk), + .a_addr(mem_addr), + .a_q(mem_din), + .a_wr(mem_wr), + .a_d(dout), + .b_addr(code_addr), + .b_q(insn)); + + reg io_wr_; + reg [15:0] mem_addr_; + reg [31:0] dout_; + always @(posedge fclk) + {io_wr_, mem_addr_, dout_} <= {io_wr, mem_addr, dout}; + + assign uart0_wr = io_wr_ & (mem_addr_ == 16'h0000); + assign uart0_rd = io_wr_ & (mem_addr_ == 16'h0002); + +endmodule -- cgit v1.2.3