Fixes to mac128k PAL simulation issues, more documentation.
This commit is contained in:
parent
c490406c81
commit
fe87fea02c
|
@ -1319,6 +1319,11 @@ module dramctl_bbu (n_res, clk, r_n_w,
|
||||||
// are in state 64.
|
// are in state 64.
|
||||||
assign bbu_dtack = drc_state[6];
|
assign bbu_dtack = drc_state[6];
|
||||||
|
|
||||||
|
// TODO FIXME Important! High speed control for column access
|
||||||
|
// strobes? The Macintosh 128K and Macintosh Plus use
|
||||||
|
// combinatorial logic to assert the *CAS signal for half of a C16M
|
||||||
|
// clock cycle, one pulse.
|
||||||
|
|
||||||
always @(negedge n_res) begin
|
always @(negedge n_res) begin
|
||||||
// Initialize all output registers on RESET.
|
// Initialize all output registers on RESET.
|
||||||
ra <= 10'bz; // Set to high-impedance to disable output.
|
ra <= 10'bz; // Set to high-impedance to disable output.
|
||||||
|
|
|
@ -56,13 +56,14 @@ module tsm(simclk, n_res,
|
||||||
// We must implement RESET for simulation or else this will never
|
// We must implement RESET for simulation or else this will never
|
||||||
// stabilize.
|
// stabilize.
|
||||||
always @(negedge n_res) begin
|
always @(negedge n_res) begin
|
||||||
casl <= 0; cash <= 0; s0 <= 0; dtack <= 0;
|
casl <= 1; cash <= 1; s0 <= 1; dtack <= 1;
|
||||||
|
|
||||||
ras <= 0; vclk <= 0; q2 <= 0; q1 <= 0;
|
ras <= 1; vclk <= 1; q2 <= 1; q1 <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate combinatorial logic sub-cycles.
|
// Simulate combinatorial logic sub-cycles.
|
||||||
always @(posedge simclk) begin
|
always @(posedge simclk) begin
|
||||||
|
if (n_res) begin
|
||||||
casl <= ~(~s0 & s1 & sysclk // video
|
casl <= ~(~s0 & s1 & sysclk // video
|
||||||
| ~s0 & ~ramen & ~lds // processor
|
| ~s0 & ~ramen & ~lds // processor
|
||||||
| ~s0 & ~casl & sysclk
|
| ~s0 & ~casl & sysclk
|
||||||
|
@ -77,22 +78,29 @@ module tsm(simclk, n_res,
|
||||||
| ~ras & ~ramen & ~s1 // guarantees that it will be recognized on the falling edge of `pclk` in state `s5`
|
| ~ras & ~ramen & ~s1 // guarantees that it will be recognized on the falling edge of `pclk` in state `s5`
|
||||||
| ~as & ~dtack & ramen // expects `as` to rise for disable
|
| ~as & ~dtack & ramen // expects `as` to rise for disable
|
||||||
| ~as & ~dtack & ~s1); // but avoid video cycles (WE)
|
| ~as & ~dtack & ~s1); // but avoid video cycles (WE)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate registered logic.
|
// Simulate registered logic.
|
||||||
always @(posedge clk) begin
|
always @(negedge clk) begin
|
||||||
ras <= ~(~pclk & q1 & s1 // video cycle
|
if (n_res) begin
|
||||||
| ~pclk & q1 & ~ramen & dtack // processor cycle
|
ras <= @(posedge clk)
|
||||||
| pclk & ~ras); // any other cycle
|
~(~pclk & q1 & s1 // video cycle
|
||||||
vclk <= ~(~q1 & pclk & q2 & vclk // divide by 8 (1MHz)
|
| ~pclk & q1 & ~ramen & dtack // processor cycle
|
||||||
| ~vclk & q1
|
| pclk & ~ras); // any other cycle
|
||||||
| ~vclk & ~pclk
|
vclk <= @(posedge clk)
|
||||||
| ~vclk & ~q2);
|
~(~q1 & pclk & q2 & vclk // divide by 8 (1MHz)
|
||||||
q1 <= ~(~pclk & q1
|
| ~vclk & q1
|
||||||
| pclk & ~q1); // divide `pclk` by 2 (4MHz)
|
| ~vclk & ~pclk
|
||||||
q2 <= ~(~q1 & pclk & q2 // divide by 4 (2MHz)
|
| ~vclk & ~q2);
|
||||||
| ~q2 & q1
|
q1 <= @(posedge clk)
|
||||||
| ~q2 & ~pclk);
|
~(~pclk & q1
|
||||||
|
| pclk & ~q1); // divide `pclk` by 2 (4MHz)
|
||||||
|
q2 <= @(posedge clk)
|
||||||
|
~(~q1 & pclk & q2 // divide by 4 (2MHz)
|
||||||
|
| ~q2 & q1
|
||||||
|
| ~q2 & ~pclk);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -119,8 +127,8 @@ module lag(simclk, n_res,
|
||||||
// We must implement RESET for simulation or else this will never
|
// We must implement RESET for simulation or else this will never
|
||||||
// stabilize.
|
// stabilize.
|
||||||
always @(negedge n_res) begin
|
always @(negedge n_res) begin
|
||||||
vshft <= 0; vsync <= 0; hsync <= 0; s1 <= 0; viapb6 <= 0;
|
vshft <= 1; vsync <= 1; hsync <= 1; s1 <= 1; viapb6 <= 1;
|
||||||
snddma <= 0; reslin <= 0; resnyb <= 0;
|
snddma <= 1; reslin <= 1; resnyb <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate combinatorial logic sub-cycles.
|
// Simulate combinatorial logic sub-cycles.
|
||||||
|
@ -128,38 +136,60 @@ module lag(simclk, n_res,
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate registered logic.
|
// Simulate registered logic.
|
||||||
always @(posedge sysclk) begin
|
always @(negedge sysclk) begin
|
||||||
vshft <= ~(s1 & ~vclk & snddma); // one pulse on the falling edge of `vclk`
|
if (n_res) begin
|
||||||
vsync <= ~(reslin
|
vshft <= @(posedge sysclk)
|
||||||
| ~vsync & ~l28);
|
~(s1 & ~vclk & snddma); // one pulse on the falling edge of `vclk`
|
||||||
hsync <= ~(viapb6 & va4 & ~va3 & ~va2 & va1 // begins in 29 (VA5)
|
vsync <= @(posedge sysclk)
|
||||||
| /*~ ???*/resnyb
|
~(reslin
|
||||||
| ~hsync & viapb6); // ends in 0F
|
| ~vsync & ~l28);
|
||||||
s1 <= ~(~p0q2 // 0 for processor and 1 for video
|
// hsync <= @(posedge sysclk)
|
||||||
| ~vclk
|
// ~(viapb6 & va4 & ~va3 & ~va2 & va1 // begins in 29 (VA5)
|
||||||
| ~vsync & hsync
|
// | /*~ ???*/resnyb
|
||||||
| ~vsync & viapb6 // only in vertical retrace we have sound cycles
|
// | ~hsync & viapb6); // ends in 0F
|
||||||
| ~viapb6 & hsync & ~va4 & ~va3 & ~va2
|
hsync <= @(posedge sysclk)
|
||||||
| ~viapb6 & ~hsync & (~va4 | va4 & ~va3 & ~va2 |
|
~(~viapb6 & ~va4 & ~va3 & va2 & va1 // begins in 29 (VA5)
|
||||||
|
| ~hsync & ~va4
|
||||||
|
| ~hsync & ~viapb6); // ends in 0F
|
||||||
|
s1 <= @(posedge sysclk)
|
||||||
|
~(~p0q2 // 0 for processor and 1 for video
|
||||||
|
| ~vclk
|
||||||
|
| ~vsync & hsync
|
||||||
|
| ~vsync & viapb6 // only in vertical retrace we have sound cycles
|
||||||
|
| ~viapb6 & hsync & ~va4 & ~va3 & ~va2
|
||||||
|
| ~viapb6 & ~hsync & (~va4 | va4 & ~va3 & ~va2 |
|
||||||
va4 & ~va3 & va2 & ~va1));
|
va4 & ~va3 & va2 & ~va1));
|
||||||
viapb6 <= ~(~hsync & resnyb // 1 indicates horizontal retrace (pseudo VA6)
|
// viapb6 <= @(posedge sysclk)
|
||||||
| va1 & ~viapb6
|
// ~(~hsync & resnyb // 1 indicates horizontal retrace (pseudo VA6)
|
||||||
| va2 & ~viapb6
|
// | va1 & ~viapb6
|
||||||
| ~hsync & ~viapb6
|
// | va2 & ~viapb6
|
||||||
| resnyb & ~viapb6
|
// | ~hsync & ~viapb6
|
||||||
| vshft & ~viapb6);
|
// | resnyb & ~viapb6
|
||||||
snddma <= ~(viapb6 & va4 & ~va3 & va2 & va1 & p0q2 & vclk & ~hsync // 0 in this output
|
// | vshft & ~viapb6);
|
||||||
| ~snddma & vclk); // ... indicates sound cycle
|
viapb6 <= @(posedge sysclk)
|
||||||
reslin <= ~(0); // ??? try to generate line 370
|
~(hsync & ~va4 & ~va3 & va2 & va1 // 1 indicates horizontal retrace (pseudo VA6)
|
||||||
resnyb <= ~(vclk // increment VA5:VA14 in 0F and 2B
|
| ~viapb6 & snddma
|
||||||
| viapb6 // ???
|
| ~viapb6 & vclk);
|
||||||
| va1
|
snddma <= @(posedge sysclk)
|
||||||
| va2
|
~(viapb6 & va4 & ~va3 & va2 & va1 & p0q2 & vclk & ~hsync // 0 in this output
|
||||||
| ~viapb6 & va3
|
| ~snddma & vclk); // ... indicates sound cycle
|
||||||
| hsync
|
reslin <= @(posedge sysclk) // try to generate line 370
|
||||||
| viapb6 & ~va3
|
~(l28
|
||||||
| ~hsync & va3 & ~va4
|
| ~vsync
|
||||||
| ~hsync & ~va3 & va4);
|
| hsync
|
||||||
|
| ~viapb6
|
||||||
|
| ~vclk);
|
||||||
|
resnyb <= @(posedge sysclk)
|
||||||
|
~(vclk // increment VA5:VA14 in 0F and 2B
|
||||||
|
| viapb6 // ???
|
||||||
|
| va1
|
||||||
|
| va2
|
||||||
|
| ~viapb6 & va3
|
||||||
|
| hsync
|
||||||
|
| viapb6 & ~va3
|
||||||
|
| ~hsync & va3 & ~va4
|
||||||
|
| ~hsync & ~va3 & va4);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -184,12 +214,13 @@ module bmu1(simclk, n_res,
|
||||||
// We must implement RESET for simulation or else this will never
|
// We must implement RESET for simulation or else this will never
|
||||||
// stabilize.
|
// stabilize.
|
||||||
always @(negedge n_res) begin
|
always @(negedge n_res) begin
|
||||||
csiwm <= 0; rd <= 0; cescc <= 0; vpa <= 0; romen <= 0;
|
csiwm <= 1; rd <= 1; cescc <= 1; vpa <= 1; romen <= 1;
|
||||||
ramen <= 0; io1 <= 0; l28 <= 0;
|
ramen <= 1; io1 <= 1; l28 <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate combinatorial logic sub-cycles.
|
// Simulate combinatorial logic sub-cycles.
|
||||||
always @(posedge simclk) begin
|
always @(posedge simclk) begin
|
||||||
|
if (n_res) begin
|
||||||
csiwm <= ~(a23 & a22 & ~a21 & ~as); // DFE1FF
|
csiwm <= ~(a23 & a22 & ~a21 & ~as); // DFE1FF
|
||||||
rd <= ~(a23 & ~a22 & ~a21 & ~as); // 9FFFF8
|
rd <= ~(a23 & ~a22 & ~a21 & ~as); // 9FFFF8
|
||||||
cescc <= ~(a23 & ~a22 & ~as); // 9FFFF8(R) or BFFFF9(W)
|
cescc <= ~(a23 & ~a22 & ~as); // 9FFFF8(R) or BFFFF9(W)
|
||||||
|
@ -205,6 +236,7 @@ module bmu1(simclk, n_res,
|
||||||
| ~l28 & ~va9
|
| ~l28 & ~va9
|
||||||
| ~l28 & ~va8
|
| ~l28 & ~va8
|
||||||
| ~l28 & ~va7);
|
| ~l28 & ~va7);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -227,26 +259,32 @@ module bmu0(simclk, n_res,
|
||||||
// We must implement RESET for simulation or else this will never
|
// We must implement RESET for simulation or else this will never
|
||||||
// stabilize.
|
// stabilize.
|
||||||
always @(negedge n_res) begin
|
always @(negedge n_res) begin
|
||||||
g244 <= 0; we <= 0;
|
g244 <= 1; we <= 1;
|
||||||
|
|
||||||
ava14 <= 0; l15 <= 0; vid <= 0; ava13 <= 0;
|
ava14 <= 1; l15 <= 1; vid <= 1; ava13 <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate combinatorial logic sub-cycles.
|
// Simulate combinatorial logic sub-cycles.
|
||||||
always @(posedge simclk) begin
|
always @(posedge simclk) begin
|
||||||
|
if (n_res) begin
|
||||||
g244 <= ~(~ramen & rw
|
g244 <= ~(~ramen & rw
|
||||||
| ~g244 & ~ramen);
|
| ~g244 & ~ramen);
|
||||||
we <= ~(~ramen & ~rw
|
we <= ~(~ramen & ~rw
|
||||||
| ~we & ~dtack); // or `dtack` is shorter before the video cycle
|
| ~we & ~dtack); // or `dtack` is shorter before the video cycle
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate registered logic.
|
// Simulate registered logic.
|
||||||
always @(posedge sysclk) begin
|
always @(negedge sysclk) begin
|
||||||
ava14 <= ~(~va14 & ~va13); // + 1
|
if (n_res) begin
|
||||||
l15 <= ~(~va14 & ~va13 & ~va12 & ~va11 & ~va10 // we haven't passed line 15
|
ava14 <= @(posedge sysclk) ~(~va14 & ~va13); // + 1
|
||||||
| va14 & ~va13 & va12 & va11 & va10); // passed by 368
|
l15 <= @(posedge sysclk)
|
||||||
vid <= ~(servid); // here we invert: blanking is in `vshft`
|
~(~va14 & ~va13 & ~va12 & ~va11 & ~va10 // we haven't passed line 15
|
||||||
ava13 <= ~(va13); // + 1
|
| va14 & ~va13 & va12 & va11 & va10); // passed by 368
|
||||||
|
vid <= @(posedge sysclk)
|
||||||
|
~(servid); // here we invert: blanking is in `vshft`
|
||||||
|
ava13 <= @(posedge sysclk) ~(va13); // + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -267,34 +305,40 @@ module tsg(simclk, n_res,
|
||||||
// We must implement RESET for simulation or else this will never
|
// We must implement RESET for simulation or else this will never
|
||||||
// stabilize.
|
// stabilize.
|
||||||
always @(negedge n_res) begin
|
always @(negedge n_res) begin
|
||||||
d0 <= 0; ipl0 <= 0;
|
d0 <= 1; ipl0 <= 1;
|
||||||
|
|
||||||
q6 <= 0; clkscc <= 0; q4 <= 0; q3 <= 0; viacb1 <= 0;
|
q6 <= 1; clkscc <= 1; q4 <= 1; q3 <= 1; viacb1 <= 1;
|
||||||
pclk <= 0;
|
pclk <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate combinatorial logic sub-cycles.
|
// Simulate combinatorial logic sub-cycles.
|
||||||
always @(posedge simclk) begin
|
always @(posedge simclk) begin
|
||||||
|
if (n_res) begin
|
||||||
ipl0 <= ~intscc | intvia; // CORRECTION
|
ipl0 <= ~intscc | intvia; // CORRECTION
|
||||||
// ipl0 <= ~(0); // ??? /M nanda
|
// ipl0 <= ~(0); // ??? /M nanda
|
||||||
d0 <= ~(~vpa & ~a19 & e); // F00000 sample the phase with 0 /n e' + usado
|
d0 <= ~(~vpa & ~a19 & e); // F00000 sample the phase with 0 /n e' + usado
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// Simulate registered logic.
|
// Simulate registered logic.
|
||||||
always @(posedge sysclk) begin
|
always @(negedge sysclk) begin
|
||||||
|
if (n_res) begin
|
||||||
// TODO VERIFY: q6 missing?
|
// TODO VERIFY: q6 missing?
|
||||||
q6 <= ~(0);
|
q6 <= @(posedge sysclk) ~(0);
|
||||||
clkscc <= ~(clkscc & ~pclk & ~q4
|
clkscc <= @(posedge sysclk)
|
||||||
| clkscc & ~pclk & ~q3
|
~(clkscc & ~pclk & ~q4
|
||||||
| clkscc & ~pclk & vclk
|
| clkscc & ~pclk & ~q3
|
||||||
| ~clkscc & pclk
|
| clkscc & ~pclk & vclk
|
||||||
| ~clkscc & q4 & q3 & ~vclk); // skip one inversion every 32 cycles
|
| ~clkscc & pclk
|
||||||
viacb1 <= ~(0); // ??? /M nanda
|
| ~clkscc & q4 & q3 & ~vclk); // skip one inversion every 32 cycles
|
||||||
pclk <= ~(pclk); // divide SYSCLK by 2 (8MHz)
|
viacb1 <= @(posedge sysclk) ~(0); // ??? /M nanda
|
||||||
q3 <= ~(~vclk); // `sysclk` / 16
|
pclk <= @(posedge sysclk) ~(pclk); // divide SYSCLK by 2 (8MHz)
|
||||||
q4 <= ~(q4 & q3 & ~vclk // `sysclk` / 32
|
q3 <= @(posedge sysclk) ~(~vclk); // `sysclk` / 16
|
||||||
| ~q4 & ~q3 // } J for generating CLKSCC
|
q4 <= @(posedge sysclk)
|
||||||
| ~q4 & vclk);
|
~(q4 & q3 & ~vclk // `sysclk` / 32
|
||||||
|
| ~q4 & ~q3 // } J for generating CLKSCC
|
||||||
|
| ~q4 & vclk);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Here's how we initialize ROM in the simulation with hex bytes (yes,
|
||||||
|
// text input) from a file:
|
||||||
|
|
||||||
|
// $readmemh("hex_memory_file.mem", memory_array, [start_address], [end_address])
|
|
@ -140,7 +140,7 @@ module ls161(n_clr, clk, a, b, c, d, enp, gnd,
|
||||||
wire [3:0] loadvec = { d, c, b, a };
|
wire [3:0] loadvec = { d, c, b, a };
|
||||||
reg [3:0] outvec;
|
reg [3:0] outvec;
|
||||||
|
|
||||||
assign rco = (outvec == 4'hf);
|
assign rco = (ent & (outvec == 4'hf));
|
||||||
assign { q_d, q_c, q_b, q_a } = outvec;
|
assign { q_d, q_c, q_b, q_a } = outvec;
|
||||||
|
|
||||||
// Clear is asynchronous, so it is not dependent on the clock.
|
// Clear is asynchronous, so it is not dependent on the clock.
|
||||||
|
@ -179,6 +179,16 @@ module ls165(sh_n_ld, clk, e, f, g, h, n_q_h, gnd,
|
||||||
assign q_h = int_reg[7];
|
assign q_h = int_reg[7];
|
||||||
assign n_q_h = ~q_h;
|
assign n_q_h = ~q_h;
|
||||||
|
|
||||||
|
// N.B. The '165 chips use asynchronous data loading. Don't
|
||||||
|
// confuse with '166! This is actuallly a continuous
|
||||||
|
// assignment... but the behavior is externally imperceptible until
|
||||||
|
// we change to shift mode, so we simply act on the rising edge of
|
||||||
|
// SH/*LD.
|
||||||
|
|
||||||
|
always @(posedge sh_n_ld) begin
|
||||||
|
int_reg <= { h, g, f, e, d, c, b, a };
|
||||||
|
end
|
||||||
|
|
||||||
// N.B. As soon as the falling edge of the clock is detected under
|
// N.B. As soon as the falling edge of the clock is detected under
|
||||||
// the proper conditions, we propagate the shifted value to the
|
// the proper conditions, we propagate the shifted value to the
|
||||||
// output pins. We do not wait until the next falling edge of the
|
// output pins. We do not wait until the next falling edge of the
|
||||||
|
@ -187,7 +197,7 @@ module ls165(sh_n_ld, clk, e, f, g, h, n_q_h, gnd,
|
||||||
if (sh_n_ld)
|
if (sh_n_ld)
|
||||||
int_reg <= { int_reg[6:0], ser };
|
int_reg <= { int_reg[6:0], ser };
|
||||||
else
|
else
|
||||||
int_reg <= { h, g, f, e, d, c, b, a };
|
; // Nothing to be done.
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -210,6 +220,9 @@ module ls166(ser, a, b, c, d, clk_inh, clk, gnd,
|
||||||
always @(negedge n_clr)
|
always @(negedge n_clr)
|
||||||
int_reg <= 0;
|
int_reg <= 0;
|
||||||
|
|
||||||
|
// N.B. The '166 chips uses synchronous data loading. Don't
|
||||||
|
// confuse with '165!
|
||||||
|
|
||||||
// N.B. As soon as the falling edge of the clock is detected under
|
// N.B. As soon as the falling edge of the clock is detected under
|
||||||
// the proper conditions, we propagate the shifted value to the
|
// the proper conditions, we propagate the shifted value to the
|
||||||
// output pins. We do not wait until the next falling edge of the
|
// output pins. We do not wait until the next falling edge of the
|
||||||
|
@ -383,13 +396,23 @@ module ls393(s1a, s1clr, s1q_a, s1q_b, s1q_c, s1q_d, gnd,
|
||||||
assign { s1q_d, s1q_c, s1q_b, s1q_a } = s1reg;
|
assign { s1q_d, s1q_c, s1q_b, s1q_a } = s1reg;
|
||||||
assign { s2q_d, s2q_c, s2q_b, s2q_a } = s2reg;
|
assign { s2q_d, s2q_c, s2q_b, s2q_a } = s2reg;
|
||||||
|
|
||||||
always @(posedge s1clr)
|
// N.B. These counters propagate the incremented value to the
|
||||||
|
// output pins on the negative edge of the A input, unlike the '161
|
||||||
|
// counter.
|
||||||
|
|
||||||
|
// Also, for the sake of simulating the Macintosh 128K Main Logic
|
||||||
|
// Board signals correctly, we must continuously evaluate the RESET
|
||||||
|
// signals (not edge evaluate), due to the fact that we can have
|
||||||
|
// glitches on the counter input while RESET is still being
|
||||||
|
// held,and the fact that we need to assert the correct RESET value
|
||||||
|
// early on.
|
||||||
|
always @(s1clr)
|
||||||
s1reg <= 0;
|
s1reg <= 0;
|
||||||
always @(posedge s1a)
|
always @(negedge s1a)
|
||||||
s1reg <= s1reg + 1;
|
s1reg <= s1reg + 1;
|
||||||
always @(posedge s2clr)
|
always @(s2clr)
|
||||||
s2reg <= 0;
|
s2reg <= 0;
|
||||||
always @(posedge s2a)
|
always @(negedge s2a)
|
||||||
s2reg <= s2reg + 1;
|
s2reg <= s2reg + 1;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -397,10 +420,10 @@ endmodule
|
||||||
// LS595: 8-bit serial input, parallel output shift register, with
|
// LS595: 8-bit serial input, parallel output shift register, with
|
||||||
// output latch.
|
// output latch.
|
||||||
module ls595(q_b, q_c, q_d, q_e, q_f, q_g, q_h, gnd,
|
module ls595(q_b, q_c, q_d, q_e, q_f, q_g, q_h, gnd,
|
||||||
n_q_h, n_srclr, srclk, rclk, n_oe, ser, vcc);
|
q_h_p, n_srclr, srclk, rclk, n_oe, ser, q_a, vcc);
|
||||||
output wire q_b, q_c, q_d, q_e, q_f, q_g, q_h;
|
output wire q_b, q_c, q_d, q_e, q_f, q_g, q_h;
|
||||||
`power wire gnd;
|
`power wire gnd;
|
||||||
output wire n_q_h;
|
output wire q_h_p;
|
||||||
input wire n_srclr, srclk, rclk, n_oe, ser;
|
input wire n_srclr, srclk, rclk, n_oe, ser;
|
||||||
output wire q_a;
|
output wire q_a;
|
||||||
`power wire vcc;
|
`power wire vcc;
|
||||||
|
@ -410,20 +433,20 @@ module ls595(q_b, q_c, q_d, q_e, q_f, q_g, q_h, gnd,
|
||||||
|
|
||||||
assign { q_h, q_g, q_f, q_e, q_d, q_c, q_b, q_a }
|
assign { q_h, q_g, q_f, q_e, q_d, q_c, q_b, q_a }
|
||||||
= (n_oe) ? 8'bz : int_reg;
|
= (n_oe) ? 8'bz : int_reg;
|
||||||
assign n_q_h = q_h;
|
assign q_h_p = q_h;
|
||||||
|
|
||||||
always @(negedge n_srclr) begin
|
always @(negedge n_srclr) begin
|
||||||
int_reg <= 0;
|
int_reg <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge srclk) begin
|
|
||||||
int_reg = { int_reg[7:1], ser };
|
|
||||||
end
|
|
||||||
|
|
||||||
// N.B. As soon as the rising edge of the clock is detected under
|
// N.B. As soon as the rising edge of the clock is detected under
|
||||||
// the proper conditions, we propagate the shifted value to the
|
// the proper conditions, we propagate the shifted value to the
|
||||||
// output pins. We do not wait until the next rising edge of the
|
// output pins. We do not wait until the next rising edge of the
|
||||||
// clock.
|
// clock.
|
||||||
|
always @(posedge srclk) begin
|
||||||
|
int_reg <= { int_reg[6:0], ser };
|
||||||
|
end
|
||||||
|
|
||||||
always @(posedge rclk) begin
|
always @(posedge rclk) begin
|
||||||
out_reg <= int_reg;
|
out_reg <= int_reg;
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue